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

SessionManager::getSessionFollowedByDrh()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 41
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 27
nc 4
nop 2
dl 0
loc 41
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
    //See BT#4871
23
    CONST SESSION_CHANGE_USER_REASON_SCHEDULE = 1;
24
    CONST SESSION_CHANGE_USER_REASON_CLASSROOM = 2;
25
    CONST SESSION_CHANGE_USER_REASON_LOCATION = 3;
26
    CONST SESSION_CHANGE_USER_REASON_ENROLLMENT_ANNULATION = 4;
27
    public static $_debug = false;
28
29
    /**
30
     * Constructor
31
     */
32
    public function __construct()
33
    {
34
    }
35
36
    /**
37
     * Fetches a session from the database
38
     * @param  int $id Session Id
39
     *
40
     * @return  array   Session details
41
     */
42
    public static function fetch($id)
43
    {
44
        $em = Database::getManager();
45
46
        if (empty($id)) {
47
            return [];
48
        }
49
50
        /** @var Session $session */
51
        $session = $em->find('ChamiloCoreBundle:Session', $id);
52
53
        if (!$session) {
54
            return [];
55
        }
56
57
        return [
58
            'id' => $session->getId(),
59
            'id_coach' => $session->getGeneralCoach() ? $session->getGeneralCoach()->getId() : null,
60
            'session_category_id' => $session->getCategory() ? $session->getCategory()->getId() : null,
61
            'name' => $session->getName(),
62
            'description' => $session->getDescription(),
63
            'show_description' => $session->getShowDescription(),
64
            'duration' => $session->getDuration(),
65
            'nbr_courses' => $session->getNbrCourses(),
66
            'nbr_users' => $session->getNbrUsers(),
67
            'nbr_classes' => $session->getNbrClasses(),
68
            'session_admin_id' => $session->getSessionAdminId(),
69
            'visibility' => $session->getVisibility(),
70
            'promotion_id' => $session->getPromotionId(),
71
            'display_start_date' => $session->getDisplayStartDate()
72
                ? $session->getDisplayStartDate()->format('Y-m-d H:i:s')
73
                : null,
74
            'display_end_date' => $session->getDisplayEndDate()
75
                ? $session->getDisplayEndDate()->format('Y-m-d H:i:s')
76
                : null,
77
            'access_start_date' => $session->getAccessStartDate()
78
                ? $session->getAccessStartDate()->format('Y-m-d H:i:s')
79
                : null,
80
            'access_end_date' => $session->getAccessEndDate()
81
                ? $session->getAccessEndDate()->format('Y-m-d H:i:s')
82
                : null,
83
            'coach_access_start_date' => $session->getCoachAccessStartDate()
84
                ? $session->getCoachAccessStartDate()->format('Y-m-d H:i:s')
85
                : null,
86
            'coach_access_end_date' => $session->getCoachAccessEndDate()
87
                ? $session->getCoachAccessEndDate()->format('Y-m-d H:i:s')
88
                : null,
89
            'send_subscription_notification' => $session->getSendSubscriptionNotification(),
90
        ];
91
    }
92
93
    /**
94
     * Create a session
95
     * @author Carlos Vargas <[email protected]>, from existing code
96
     * @param   string  $name
97
     * @param   string  $startDate (YYYY-MM-DD hh:mm:ss)
98
     * @param   string  $endDate (YYYY-MM-DD hh:mm:ss)
99
     * @param   string  $displayStartDate (YYYY-MM-DD hh:mm:ss)
100
     * @param   string  $displayEndDate (YYYY-MM-DD hh:mm:ss)
101
     * @param   string  $coachStartDate (YYYY-MM-DD hh:mm:ss)
102
     * @param   string  $coachEndDate (YYYY-MM-DD hh:mm:ss)
103
     * @param   mixed   $coachId If integer, this is the session coach id, if string, the coach ID will be looked for from the user table
104
     * @param   integer $sessionCategoryId ID of the session category in which this session is registered
105
     * @param   integer $visibility Visibility after end date (0 = read-only, 1 = invisible, 2 = accessible)
106
     * @param   bool    $fixSessionNameIfExists
107
     * @param   string  $duration
108
     * @param   string  $description Optional. The session description
109
     * @param   int     $showDescription Optional. Whether show the session description
110
     * @param   array   $extraFields
111
     * @param   int     $sessionAdminId Optional. If this sessions was created by a session admin, assign it to him
112
     * @param boolean $sendSubscriptionNotification Optional.
113
     *          Whether send a mail notification to users being subscribed
114
     * @todo use an array to replace all this parameters or use the model.lib.php ...
115
     * @return mixed       Session ID on success, error message otherwise
116
     * */
117
    public static function create_session(
118
        $name,
119
        $startDate,
120
        $endDate,
121
        $displayStartDate,
122
        $displayEndDate,
123
        $coachStartDate,
124
        $coachEndDate,
125
        $coachId,
126
        $sessionCategoryId,
127
        $visibility = 1,
128
        $fixSessionNameIfExists = false,
129
        $duration = null,
130
        $description = null,
131
        $showDescription = 0,
132
        $extraFields = array(),
133
        $sessionAdminId = 0,
134
        $sendSubscriptionNotification = false
135
    ) {
136
        global $_configuration;
137
138
        //Check portal limits
139
        $access_url_id = 1;
140
141
        if (api_get_multiple_access_url()) {
142
            $access_url_id = api_get_current_access_url_id();
143
        }
144
145
        if (is_array($_configuration[$access_url_id]) &&
146
            isset($_configuration[$access_url_id]['hosting_limit_sessions']) &&
147
            $_configuration[$access_url_id]['hosting_limit_sessions'] > 0
148
        ) {
149
            $num = self::count_sessions();
150
            if ($num >= $_configuration[$access_url_id]['hosting_limit_sessions']) {
151
                api_warn_hosting_contact('hosting_limit_sessions');
152
                return get_lang('PortalSessionsLimitReached');
153
            }
154
        }
155
156
        $name = Database::escape_string(trim($name));
157
        $sessionCategoryId = intval($sessionCategoryId);
158
        $visibility = intval($visibility);
159
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
160
161
        $startDate = Database::escape_string($startDate);
162
        $endDate = Database::escape_string($endDate);
163
164
        if (empty($name)) {
165
            $msg = get_lang('SessionNameIsRequired');
166
            return $msg;
167
        } elseif (empty($coachId)) {
168
            $msg = get_lang('CoachIsRequired');
169
            return $msg;
170
        } elseif (!empty($startDate) && !api_is_valid_date($startDate, 'Y-m-d H:i') && !api_is_valid_date($startDate, 'Y-m-d H:i:s')) {
171
            $msg = get_lang('InvalidStartDate');
172
            return $msg;
173
        } elseif (!empty($endDate) && !api_is_valid_date($endDate, 'Y-m-d H:i') && !api_is_valid_date($endDate, 'Y-m-d H:i:s')) {
174
            $msg = get_lang('InvalidEndDate');
175
            return $msg;
176
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
177
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
178
            return $msg;
179
        } else {
180
            $ready_to_create = false;
181
            if ($fixSessionNameIfExists) {
182
                $name = self::generateNextSessionName($name);
183
                if ($name) {
184
                    $ready_to_create = true;
185
                } else {
186
                    $msg = get_lang('SessionNameAlreadyExists');
187
                    return $msg;
188
                }
189
            } else {
190
                $rs = Database::query("SELECT 1 FROM $tbl_session WHERE name='" . $name . "'");
191
                if (Database::num_rows($rs)) {
192
                    $msg = get_lang('SessionNameAlreadyExists');
193
                    return $msg;
194
                }
195
                $ready_to_create = true;
196
            }
197
198
            if ($ready_to_create) {
199
                $sessionAdminId = !empty($sessionAdminId) ? $sessionAdminId : api_get_user_id();
200
                $values = array(
201
                    'name' => $name,
202
                    'id_coach' => $coachId,
203
                    'session_admin_id' => $sessionAdminId,
204
                    'visibility' => $visibility,
205
                    'description' => $description,
206
                    'show_description' => intval($showDescription),
207
                    'send_subscription_notification' => (int) $sendSubscriptionNotification,
208
                );
209
210
                if (!empty($startDate)) {
211
                    $values['access_start_date'] = api_get_utc_datetime($startDate);
212
                }
213
214
                if (!empty($endDate)) {
215
                    $values['access_end_date'] = api_get_utc_datetime($endDate);
216
                }
217
218
                if (!empty($displayStartDate)) {
219
                    $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
220
                }
221
222
                if (!empty($displayEndDate)) {
223
                    $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
224
                }
225
226
                if (!empty($coachStartDate)) {
227
                    $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
228
                }
229
                if (!empty($coachEndDate)) {
230
                    $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
231
                }
232
233
                if (!empty($sessionCategoryId)) {
234
                    $values['session_category_id'] = $sessionCategoryId;
235
                }
236
237
                $session_id = Database::insert($tbl_session, $values);
238
239
                $duration = intval($duration);
240
241 View Code Duplication
                if (!empty($duration)) {
242
                    $sql = "UPDATE $tbl_session SET
243
                        access_start_date = NULL,
244
                        access_end_date = NULL,
245
                        display_start_date = NULL,
246
                        display_end_date = NULL,
247
                        coach_access_start_date = NULL,
248
                        coach_access_end_date = NULL,
249
                        duration = $duration
250
                    WHERE id = $session_id";
251
                    Database::query($sql);
252
                } else {
253
                    $sql = "UPDATE $tbl_session
254
                        SET duration = 0
255
                        WHERE id = $session_id";
256
                    Database::query($sql);
257
                }
258
259
                if (!empty($session_id)) {
260
                    $extraFields['item_id'] = $session_id;
261
262
                    $sessionFieldValue = new ExtraFieldValue('session');
263
                    $sessionFieldValue->saveFieldValues($extraFields);
264
265
                    /*
266
                      Sends a message to the user_id = 1
267
268
                      $user_info = api_get_user_info(1);
269
                      $complete_name = $user_info['firstname'].' '.$user_info['lastname'];
270
                      $subject = api_get_setting('siteName').' - '.get_lang('ANewSessionWasCreated');
271
                      $message = get_lang('ANewSessionWasCreated')." <br /> ".get_lang('NameOfTheSession').' : '.$name;
272
                      api_mail_html($complete_name, $user_info['email'], $subject, $message);
273
                     *
274
                     */
275
                    //Adding to the correct URL
276
                    $access_url_id = api_get_current_access_url_id();
277
                    UrlManager::add_session_to_url($session_id, $access_url_id);
278
279
                    // add event to system log
280
                    $user_id = api_get_user_id();
281
                    Event::addEvent(
282
                        LOG_SESSION_CREATE,
283
                        LOG_SESSION_ID,
284
                        $session_id,
285
                        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...
286
                        $user_id
287
                    );
288
                }
289
290
                return $session_id;
291
            }
292
        }
293
    }
294
295
    /**
296
     * @param string $name
297
     *
298
     * @return bool
299
     */
300 View Code Duplication
    public static function session_name_exists($name)
301
    {
302
        $name = Database::escape_string($name);
303
        $sql = "SELECT COUNT(*) as count FROM " . Database::get_main_table(TABLE_MAIN_SESSION) . "
304
                WHERE name = '$name'";
305
        $result = Database::fetch_array(Database::query($sql));
306
307
        return $result['count'] > 0;
308
    }
309
310
    /**
311
     * @param string $where_condition
312
     *
313
     * @return mixed
314
     */
315
    public static function get_count_admin($where_condition = '')
316
    {
317
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
318
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
319
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
320
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
321
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
322
323
        $where = 'WHERE 1=1 ';
324
        $user_id = api_get_user_id();
325
326
        $extraJoin = '';
327
328
        if (api_is_session_admin() &&
329
            api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
330
        ) {
331
            $where .= " AND (
332
                            s.session_admin_id = $user_id  OR
333
                            sru.user_id = '$user_id' AND
334
                            sru.relation_type = '" . SESSION_RELATION_TYPE_RRHH . "'
335
                            )
336
                      ";
337
338
            $extraJoin = " INNER JOIN $tbl_session_rel_user sru
339
                           ON sru.session_id = s.id ";
340
        }
341
342
        $today = api_get_utc_datetime();
343
        $today = api_strtotime($today, 'UTC');
0 ignored issues
show
Bug introduced by
It seems like $today defined by api_strtotime($today, 'UTC') on line 343 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...
344
        $today = date('Y-m-d', $today);
345
346
        if (!empty($where_condition)) {
347
            $where_condition = str_replace("(  session_active = ':'  )", '1=1', $where_condition);
348
349
            $where_condition = str_replace('category_name', 'sc.name', $where_condition);
350
            $where_condition = str_replace(
351
                array("AND session_active = '1'  )", " AND (  session_active = '1'  )"),
352
                array(') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 " )
353
                , $where_condition
354
            );
355
            $where_condition = str_replace(
356
                array("AND session_active = '0'  )", " AND (  session_active = '0'  )"),
357
                array(') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "),
358
                $where_condition
359
            );
360
        } else {
361
            $where_condition = " AND 1 = 1";
362
        }
363
364
        $courseCondition = null;
365
        if (strpos($where_condition, 'c.id')) {
366
            $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
367
            $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
368
            $courseCondition = " INNER JOIN $table course_rel_session
369
                                 ON (s.id = course_rel_session.session_id)
370
                                 INNER JOIN $tableCourse c
371
                                 ON (course_rel_session.c_id = c.id)
372
                                ";
373
        }
374
375
        $sql = "SELECT COUNT(id) as total_rows FROM (
376
                SELECT DISTINCT
377
                 IF (
378
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
379
                    (s.access_start_date IS NULL AND s.access_end_date  = IS NULL ) OR
380
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
381
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
382
				, 1, 0) as session_active,
383
                s.id
384
                FROM $tbl_session s
385
                LEFT JOIN $tbl_session_category sc
386
                ON s.session_category_id = sc.id
387
                INNER JOIN $tbl_user u
388
                ON s.id_coach = u.user_id
389
                $courseCondition
390
                $extraJoin
391
                $where $where_condition ) as session_table";
392
393
        if (api_is_multiple_url_enabled()) {
394
395
            $access_url_id = api_get_current_access_url_id();
396
            if ($access_url_id != -1) {
397
                $where.= " AND ar.access_url_id = $access_url_id ";
398
399
                $sql = "SELECT count(id) as total_rows FROM (
400
                SELECT DISTINCT
401
                  IF (
402
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
403
                    (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
404
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
405
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
406
				, 1, 0)
407
				as session_active,
408
				s.id
409
                FROM $tbl_session s
410
                    LEFT JOIN  $tbl_session_category sc
411
                    ON s.session_category_id = sc.id
412
                    INNER JOIN $tbl_user u ON s.id_coach = u.user_id
413
                    INNER JOIN $table_access_url_rel_session ar
414
                    ON ar.session_id = s.id
415
                    $courseCondition
416
                    $extraJoin
417
                $where $where_condition) as session_table";
418
            }
419
        }
420
421
        $result_rows = Database::query($sql);
422
        $row = Database::fetch_array($result_rows);
423
        $num = $row['total_rows'];
424
425
        return $num;
426
    }
427
428
    /**
429
     * Gets the admin session list callback of the session/session_list.php page
430
     * @param array $options order and limit keys
431
     * @param boolean $get_count Whether to get all the results or only the count
432
     * @return mixed Integer for number of rows, or array of results
433
     * @assert (array(),true) !== false
434
     */
435
    public static function get_sessions_admin($options = array(), $get_count = false)
436
    {
437
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
438
        $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
439
440
        $where = 'WHERE 1 = 1 ';
441
        $user_id = api_get_user_id();
442
443 View Code Duplication
        if (!api_is_platform_admin()) {
444
            if (api_is_session_admin() &&
445
                api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
446
            ) {
447
                $where .=" AND s.session_admin_id = $user_id ";
448
            }
449
        }
450
451
        if (!api_is_platform_admin() && api_is_teacher() &&
452
            api_get_setting('allow_teachers_to_create_sessions') == 'true'
453
        ) {
454
            $where .=" AND s.id_coach = $user_id ";
455
        }
456
457
        $extra_field = new ExtraFieldModel('session');
458
        $conditions = $extra_field->parseConditions($options);
459
        $inject_joins = $conditions['inject_joins'];
460
        $where .= $conditions['where'];
461
        $inject_where = $conditions['inject_where'];
462
        $inject_extra_fields = $conditions['inject_extra_fields'];
463
464
        $order = $conditions['order'];
465
        $limit = $conditions['limit'];
466
467
        $isMakingOrder = false;
468
469
        if ($get_count == true) {
470
            $select = " SELECT count(DISTINCT s.id) as total_rows";
471
        } else {
472
            $select =
473
                "SELECT DISTINCT 
474
                     s.name,
475
                     s.display_start_date, 
476
                     s.display_end_date, 
477
                     access_start_date, 
478
                     access_end_date, 
479
                     s.visibility, 
480
                     s.session_category_id, 
481
                     $inject_extra_fields 
482
                     s.id 
483
             ";
484
485
            $isMakingOrder = strpos($options['order'], 'category_name') === 0;
486
        }
487
488
        $isFilteringSessionCategory = strpos($where, 'category_name') !== false;
489
        $isFilteringSessionCategoryWithName = strpos($where, 'sc.name') !== false;
490
491
        if ($isMakingOrder || $isFilteringSessionCategory || $isFilteringSessionCategoryWithName) {
492
            $inject_joins .= " LEFT JOIN $sessionCategoryTable sc ON s.session_category_id = sc.id ";
493
494
            if ($isFilteringSessionCategory) {
495
                $where = str_replace('category_name', 'sc.name', $where);
496
            }
497
498
            if ($isMakingOrder) {
499
                $order = str_replace('category_name', 'sc.name', $order);
500
            }
501
        }
502
503
        $query = "$select FROM $tbl_session s $inject_joins $where $inject_where";
504
505
        if (api_is_multiple_url_enabled()) {
506
            $table_access_url_rel_session= Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
507
            $access_url_id = api_get_current_access_url_id();
508
            if ($access_url_id != -1) {
509
                $where.= " AND ar.access_url_id = $access_url_id ";
510
                $query = "$select
511
                        FROM $tbl_session s $inject_joins
512
                        INNER JOIN $table_access_url_rel_session ar
513
                        ON (ar.session_id = s.id) $where";
514
            }
515
        }
516
517
        $query .= $order;
518
        $query .= $limit;
519
        $result = Database::query($query);
520
521
        $categories = self::get_all_session_category();
522
        $orderedCategories = array();
523
        if (!empty($categories)) {
524
            foreach ($categories as $category) {
525
                $orderedCategories[$category['id']] = $category['name'];
526
            }
527
        }
528
529
        $formatted_sessions = array();
530
        if (Database::num_rows($result)) {
531
            $sessions = Database::store_result($result, 'ASSOC');
532
            if ($get_count) {
533
                return $sessions[0]['total_rows'];
534
            }
535
536
            foreach ($sessions as $session) {
537
                $session_id = $session['id'];
538
                $session['name'] = Display::url($session['name'], "resume_session.php?id_session=".$session['id']);
539
540 View Code Duplication
                if (isset($session['session_active']) && $session['session_active'] == 1) {
541
                    $session['session_active'] = Display::return_icon('accept.png', get_lang('Active'), array(), ICON_SIZE_SMALL);
542
                } else {
543
                    $session['session_active'] = Display::return_icon('error.png', get_lang('Inactive'), array(), ICON_SIZE_SMALL);
544
                }
545
546
                $session = self::convert_dates_to_local($session, true);
547
548 View Code Duplication
                switch ($session['visibility']) {
549
                    case SESSION_VISIBLE_READ_ONLY: //1
550
                        $session['visibility'] = get_lang('ReadOnly');
551
                        break;
552
                    case SESSION_VISIBLE:           //2
553
                    case SESSION_AVAILABLE:         //4
554
                        $session['visibility'] = get_lang('Visible');
555
                        break;
556
                    case SESSION_INVISIBLE:         //3
557
                        $session['visibility'] = api_ucfirst(get_lang('Invisible'));
558
                        break;
559
                }
560
561
                // Cleaning double selects.
562 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...
563
                    if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
564
                        $options = explode('::', $value);
565
                    }
566
                    $original_key = $key;
567
568
                    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...
569
                    } else {
570
                        $key = str_replace('_second', '', $key);
571
                    }
572
573
                    if (isset($options_by_double[$key])) {
574
                        if (isset($options[0])) {
575
                            if (isset($options_by_double[$key][$options[0]])) {
576
                                if (strpos($original_key, '_second') === false) {
577
                                    $value = $options_by_double[$key][$options[0]]['option_display_text'];
578
                                } else {
579
                                    $value = $options_by_double[$key][$options[1]]['option_display_text'];
580
                                }
581
                            }
582
                        }
583
                    }
584
                }
585
                $formatted_sessions[$session_id] = $session;
586
                $categoryName = isset($orderedCategories[$session['session_category_id']]) ? $orderedCategories[$session['session_category_id']] : '';
587
                $formatted_sessions[$session_id]['category_name'] = $categoryName;
588
            }
589
        }
590
        return $formatted_sessions;
591
    }
592
593
    /**
594
     *  Get total of records for progress of learning paths in the given session
595
     *  @param int session id
596
     *  @return int
597
     */
598
    public static function get_count_session_lp_progress($sessionId = 0)
599
    {
600
        $tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
601
        $tbl_lp_view = Database::get_course_table(TABLE_LP_VIEW);
602
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
603
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
604
605
        $sessionId = intval($sessionId);
606
607
        $sql = "SELECT  count(*) as total_rows
608
                FROM $tbl_lp_view v
609
                INNER JOIN $tbl_lp l ON l.id = v.lp_id
610
                INNER JOIN $tbl_user u ON u.user_id = v.user_id
611
                INNER JOIN $tbl_course c
612
                WHERE v.session_id = " . $sessionId;
613
        $result_rows = Database::query($sql);
614
        $row = Database::fetch_array($result_rows);
615
        $num = $row['total_rows'];
616
617
        return $num;
618
    }
619
620
    /**
621
     * Gets the progress of learning paths in the given session
622
     * @param int   $sessionId
623
     * @param int $courseId
624
     * @param string $date_from
625
     * @param string $date_to
626
     * @param array options order and limit keys
627
     * @return array table with user name, lp name, progress
628
     */
629
    public static function get_session_lp_progress($sessionId = 0, $courseId = 0, $date_from, $date_to, $options)
630
    {
631
        //escaping vars
632
        $sessionId = $sessionId == 'T' ? 'T' : intval($sessionId);
633
        $courseId = intval($courseId);
634
        $date_from = Database::escape_string($date_from);
635
        $date_to = Database::escape_string($date_to);
636
637
        //tables
638
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
639
        $user = Database::get_main_table(TABLE_MAIN_USER);
640
        $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
641
642
        $course = api_get_course_info_by_id($courseId);
643
644
        //getting all the students of the course
645
        //we are not using this because it only returns user ids
646
        /* if (empty($sessionId)
647
          {
648
          // Registered students in a course outside session.
649
          $users = CourseManager::get_student_list_from_course_code($course_code);
650
          } else {
651
          // Registered students in session.
652
          $users = CourseManager::get_student_list_from_course_code($course_code, true, $sessionId);
653
          } */
654
655
        $sessionCond = 'and session_id = %s';
656
        if ($sessionId == 'T') {
657
            $sessionCond = "";
658
        }
659
660
        $where = " WHERE c_id = '%s' AND s.status <> 2 $sessionCond";
661
662
        $limit = null;
663
        if (!empty($options['limit'])) {
664
            $limit = " LIMIT " . $options['limit'];
665
        }
666
667
        if (!empty($options['where'])) {
668
            $where .= ' '.$options['where'];
669
        }
670
671
        $order = null;
672
        if (!empty($options['order'])) {
673
            $order = " ORDER BY " . $options['order'];
674
        }
675
676
        $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
677
                FROM $session_course_user s
678
                INNER JOIN $user u ON u.user_id = s.user_id
679
                $where
680
                $order
681
                $limit";
682
683
        $sql_query = sprintf($sql, Database::escape_string($course['real_id']), $sessionId);
684
685
        $rs = Database::query($sql_query);
686
        while ($user = Database::fetch_array($rs)) {
687
            $users[$user['user_id']] = $user;
688
        }
689
690
        //Get lessons
691
        $lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
692
693
        $table = array();
694
        foreach ($users as $user) {
695
            $data = array(
696
                'lastname' => $user[1],
697
                'firstname' => $user[2],
698
                'username' => $user[3],
699
            );
700
701
            $sessionCond = 'AND v.session_id = %d';
702
            if ($sessionId == 'T') {
703
                $sessionCond = "";
704
            }
705
706
            //Get lessons progress by user
707
            $sql = "SELECT v.lp_id as id, v.progress
708
                    FROM  $tbl_course_lp_view v
709
                    WHERE v.c_id = %d
710
                    AND v.user_id = %d
711
            $sessionCond";
712
713
            $sql_query = sprintf($sql,
714
                intval($courseId),
715
                intval($user['user_id']),
716
                $sessionId
717
            );
718
719
            $result = Database::query($sql_query);
720
721
            $user_lessons = array();
722
            while ($row = Database::fetch_array($result)) {
723
                $user_lessons[$row['id']] = $row;
724
            }
725
726
            //Match course lessons with user progress
727
            $progress = 0;
728
            $count = 0;
729
            foreach ($lessons as $lesson) {
730
                $data[$lesson['id']] = (!empty($user_lessons[$lesson['id']]['progress'])) ? $user_lessons[$lesson['id']]['progress'] : 0;
731
                $progress += $data[$lesson['id']];
732
                $data[$lesson['id']] = $data[$lesson['id']] . '%';
733
                $count++;
734
            }
735
            if ($count == 0) {
736
                $data['total'] = 0;
737
            } else {
738
                $data['total'] = round($progress / $count, 2) . '%';
739
            }
740
            $table[] = $data;
741
        }
742
743
        return $table;
744
    }
745
746
    /**
747
     * Gets the survey answers
748
     * @param int   $sessionId
749
     * @param int   $courseId
750
     * @param int   $surveyId
751
     * @param array options order and limit keys
752
     * @todo fix the query
753
     * @return array table with user name, lp name, progress
754
     */
755
    public static function get_survey_overview($sessionId = 0, $courseId = 0, $surveyId = 0, $date_from, $date_to, $options)
756
    {
757
        //escaping vars
758
        $sessionId = intval($sessionId);
759
        $courseId = intval($courseId);
760
        $surveyId = intval($surveyId);
761
        $date_from = Database::escape_string($date_from);
762
        $date_to = Database::escape_string($date_to);
763
764
        //tables
765
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
766
        $user = Database::get_main_table(TABLE_MAIN_USER);
767
        $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
768
        $c_survey = Database::get_course_table(TABLE_SURVEY);
769
        $c_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
770
        $c_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
771
        $c_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
772
773
        $course = api_get_course_info_by_id($courseId);
774
775
        $where = " WHERE c_id = '%s' AND s.status <> 2 AND session_id = %s";
776
777
        $limit = null;
778
        if (!empty($options['limit'])) {
779
            $limit = " LIMIT " . $options['limit'];
780
        }
781
782
        if (!empty($options['where'])) {
783
            $where .= ' '.$options['where'];
784
        }
785
786
        $order = null;
787
        if (!empty($options['order'])) {
788
            $order = " ORDER BY " . $options['order'];
789
        }
790
791
        $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
792
                FROM $session_course_user s
793
                INNER JOIN $user u ON u.user_id = s.user_id
794
                $where $order $limit";
795
796
        $sql_query = sprintf($sql, intval($course['real_id']), $sessionId);
797
        $rs = Database::query($sql_query);
798
        while ($user = Database::fetch_array($rs)) {
799
            $users[$user['user_id']] = $user;
800
        }
801
802
        //Get survey questions
803
        $questions = SurveyManager::get_questions($surveyId, $courseId);
804
805
        //Survey is anonymous?
806
        $result = Database::query(sprintf("SELECT anonymous FROM $c_survey WHERE survey_id = %d", $surveyId));
807
        $row = Database::fetch_array($result);
808
        $anonymous = ($row['anonymous'] == 1) ? true : false;
809
810
        $table = array();
811
        foreach ($users as $user) {
812
            $data = array(
813
                'lastname' => ($anonymous ? '***' : $user[1]),
814
                'firstname' => ($anonymous ? '***' : $user[2]),
815
                'username' => ($anonymous ? '***' : $user[3]),
816
            );
817
818
            //Get questions by user
819
            $sql = "SELECT sa.question_id, sa.option_id, sqo.option_text, sq.type
820
                    FROM $c_survey_answer sa
821
                    INNER JOIN $c_survey_question sq
822
                    ON sq.question_id = sa.question_id
823
                    LEFT JOIN $c_survey_question_option sqo
824
                    ON
825
                      sqo.c_id = sa.c_id AND
826
                      sqo.question_id = sq.question_id AND
827
                      sqo.question_option_id = sa.option_id AND
828
                      sqo.survey_id = sq.survey_id
829
                    WHERE
830
                      sa.survey_id = %d AND
831
                      sa.c_id = %d AND
832
                      sa.user = %d
833
            "; //. $where_survey;
834
            $sql_query = sprintf($sql, $surveyId, $courseId, $user['user_id']);
835
836
            $result = Database::query($sql_query);
837
838
            $user_questions = array();
839
            while ($row = Database::fetch_array($result)) {
840
                $user_questions[$row['question_id']] = $row;
841
            }
842
843
            //Match course lessons with user progress
844
            foreach ($questions as $question_id => $question) {
845
                $option_text = 'option_text';
846
                if ($user_questions[$question_id]['type'] == 'open') {
847
                    $option_text = 'option_id';
848
                }
849
                $data[$question_id] = $user_questions[$question_id][$option_text];
850
            }
851
852
            $table[] = $data;
853
        }
854
        return $table;
855
    }
856
857
    /**
858
     * Gets the progress of the given session
859
     * @param int   $sessionId
860
     * @param int   $courseId
861
     * @param array options order and limit keys
862
     *
863
     * @return array table with user name, lp name, progress
864
     */
865
    public static function get_session_progress($sessionId, $courseId, $date_from, $date_to, $options)
866
    {
867
        $sessionId = intval($sessionId);
868
869
        $getAllSessions = false;
870
        if (empty($sessionId)) {
871
            $sessionId = 0;
872
            $getAllSessions = true;
873
        }
874
875
        //tables
876
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
877
        $user = Database::get_main_table(TABLE_MAIN_USER);
878
        $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
879
        $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
880
        $tbl_course_lp = Database::get_course_table(TABLE_LP_MAIN);
881
        $wiki = Database::get_course_table(TABLE_WIKI);
882
        $table_stats_default = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
883
        $table_stats_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
884
885
        $course = api_get_course_info_by_id($courseId);
886
        $where = " WHERE c_id = '%s' AND s.status <> 2 ";
887
888
        $limit = null;
889
        if (!empty($options['limit'])) {
890
            $limit = " LIMIT " . $options['limit'];
891
        }
892
893
        if (!empty($options['where'])) {
894
            $where .= ' '.$options['where'];
895
        }
896
897
        $order = null;
898
        if (!empty($options['order'])) {
899
            $order = " ORDER BY " . $options['order'];
900
        }
901
902
        //TODO, fix create report without session
903
        $queryVariables = array($course['real_id']);
904
        if (!empty($sessionId)) {
905
            $where .= ' AND session_id = %s';
906
            $queryVariables[] = $sessionId;
907
            $sql = "SELECT
908
                        u.user_id, u.lastname, u.firstname, u.username,
909
                        u.email, s.c_id, s.session_id
910
                    FROM $session_course_user s
911
                    INNER JOIN $user u
912
                    ON u.user_id = s.user_id
913
                    $where $order $limit";
914
        } else {
915
            $sql = "SELECT
916
                        u.user_id, u.lastname, u.firstname, u.username,
917
                        u.email, s.c_id, s.session_id
918
                    FROM $session_course_user s
919
                    INNER JOIN $user u ON u.user_id = s.user_id
920
                    $where $order $limit";
921
        }
922
923
        $sql_query = vsprintf($sql, $queryVariables);
924
        $rs = Database::query($sql_query);
925
        while ($user = Database::fetch_array($rs)) {
926
            $users[$user['user_id']] = $user;
927
        }
928
929
        /**
930
         *  Lessons
931
         */
932
        $sql = "SELECT * FROM $tbl_course_lp WHERE c_id = %s ";  //AND session_id = %s
933
        $sql_query = sprintf($sql, $course['real_id']);
934
        $result = Database::query($sql_query);
935
        $arrLesson = array(array());
936 View Code Duplication
        while ($row = Database::fetch_array($result)) {
937
            if (empty($arrLesson[$row['session_id']]['lessons_total'])) {
938
                $arrLesson[$row['session_id']]['lessons_total'] = 1;
939
            } else {
940
                $arrLesson[$row['session_id']]['lessons_total'] ++;
941
            }
942
        }
943
944
        /**
945
         *  Exercises
946
         */
947
        $exercises = ExerciseLib::get_all_exercises($course, $sessionId, false, '', $getAllSessions);
948
        $exercises_total = count($exercises);
949
950
        /**
951
         *  Assignments
952
         */
953
        //total
954
        $params = [$course['real_id']];
955
        if ($getAllSessions) {
956
            $sql = "SELECT count(w.id) as count
957
                    FROM $workTable w
958
                    LEFT JOIN $workTableAssignment a
959
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
960
                    WHERE 
961
                        w.c_id = %s AND 
962
                        parent_id = 0 AND 
963
                        active IN (1, 0)";
964
        } else {
965
            $sql = "SELECT count(w.id) as count
966
                    FROM $workTable w
967
                    LEFT JOIN $workTableAssignment a
968
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
969
                    WHERE 
970
                        w.c_id = %s AND 
971
                        parent_id = 0 AND 
972
                        active IN (1, 0)";
973
974
            if (empty($sessionId)) {
975
                $sql .= ' AND w.session_id = NULL ';
976
            } else {
977
                $sql .= ' AND w.session_id = %s ';
978
                $params[] = $sessionId;
979
            }
980
        }
981
982
        $sql_query = vsprintf($sql, $params);
983
        $result = Database::query($sql_query);
984
        $row = Database::fetch_array($result);
985
        $assignments_total = $row['count'];
986
987
        /**
988
         * Wiki
989
         */
990
        if ($getAllSessions) {
991
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
992
                    WHERE c_id = %s";
993
        } else {
994
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
995
                    WHERE c_id = %s and session_id = %s";
996
        }
997
        $sql_query = sprintf($sql, $course['real_id'], $sessionId);
998
        $result = Database::query($sql_query);
999
        $row = Database::fetch_array($result);
1000
        $wiki_total = $row['count'];
1001
1002
        /**
1003
         * Surveys
1004
         */
1005
        $survey_user_list = array();
1006
        $survey_list = SurveyManager::get_surveys($course['code'], $sessionId);
1007
1008
        $surveys_total = count($survey_list);
1009 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...
1010
            $user_list = SurveyManager::get_people_who_filled_survey(
1011
                $survey['survey_id'],
1012
                false,
1013
                $course['real_id']
1014
            );
1015
            foreach ($user_list as $user_id) {
1016
                isset($survey_user_list[$user_id]) ? $survey_user_list[$user_id] ++ : $survey_user_list[$user_id] = 1;
1017
            }
1018
        }
1019
1020
        /**
1021
         * Forums
1022
         */
1023
        $forums_total = CourseManager::getCountForum(
1024
            $course['real_id'],
1025
            $sessionId,
1026
            $getAllSessions
1027
        );
1028
1029
        //process table info
1030
        foreach ($users as $user) {
1031
            //Course description
1032
            $sql = "SELECT count(*) as count
1033
                    FROM $table_stats_access
1034
                    WHERE access_tool = 'course_description'
1035
                    AND c_id = '%s'
1036
                    AND access_session_id = %s
1037
                    AND access_user_id = %s ";
1038
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1039
1040
            $result = Database::query($sql_query);
1041
            $row = Database::fetch_array($result);
1042
            $course_description_progress = ($row['count'] > 0) ? 100 : 0;
1043
1044
            if (!empty($arrLesson[$user['id_session']]['lessons_total'])) {
1045
                $lessons_total = $arrLesson[$user['id_session']]['lessons_total'];
1046
            } else {
1047
                $lessons_total = !empty($arrLesson[0]['lessons_total']) ? $arrLesson[0]['lessons_total'] : 0;
1048
            }
1049
1050
            //Lessons
1051
            //TODO: Lessons done and left is calculated by progress per item in lesson, maybe we should calculate it only per completed lesson?
1052
            $lessons_progress = Tracking::get_avg_student_progress(
1053
                $user['user_id'],
1054
                $course['code'],
1055
                array(),
1056
                $user['id_session']
1057
            );
1058
            $lessons_done = ($lessons_progress * $lessons_total) / 100;
1059
            $lessons_left = $lessons_total - $lessons_done;
1060
1061
            //Exercises
1062
            $exercises_progress = str_replace('%', '', Tracking::get_exercise_student_progress($exercises, $user['user_id'], $course['real_id'], $user['id_session']));
1063
            $exercises_done = round(($exercises_progress * $exercises_total) / 100);
1064
            $exercises_left = $exercises_total - $exercises_done;
1065
1066
            //Assignments
1067
            $assignments_done = Tracking::count_student_assignments($user['user_id'], $course['code'], $user['id_session']);
1068
            $assignments_left = $assignments_total - $assignments_done;
1069
            if (!empty($assignments_total)) {
1070
                $assignments_progress = round((( $assignments_done * 100 ) / $assignments_total), 2);
1071
            } else {
1072
                $assignments_progress = 0;
1073
            }
1074
1075
            //Wiki
1076
            //total revisions per user
1077
            $sql = "SELECT count(*) as count
1078
                    FROM $wiki
1079
                    WHERE c_id = %s and session_id = %s and user_id = %s";
1080
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1081
            $result = Database::query($sql_query);
1082
            $row = Database::fetch_array($result);
1083
            $wiki_revisions = $row['count'];
1084
            //count visited wiki pages
1085
            $sql = "SELECT count(distinct default_value) as count
1086
                    FROM $table_stats_default
1087
                    WHERE
1088
                        default_user_id = %s AND
1089
                        default_event_type = 'wiki_page_view' AND
1090
                        default_value_type = 'wiki_page_id' AND
1091
                        c_id = %s
1092
                    ";
1093
            $sql_query = sprintf($sql, $user['user_id'], $course['real_id']);
1094
            $result = Database::query($sql_query);
1095
            $row = Database::fetch_array($result);
1096
1097
            $wiki_read = $row['count'];
1098
            $wiki_unread = $wiki_total - $wiki_read;
1099
            if (!empty($wiki_total)) {
1100
                $wiki_progress = round((( $wiki_read * 100 ) / $wiki_total), 2);
1101
            } else {
1102
                $wiki_progress = 0;
1103
            }
1104
1105
            //Surveys
1106
            $surveys_done = (isset($survey_user_list[$user['user_id']]) ? $survey_user_list[$user['user_id']] : 0);
1107
            $surveys_left = $surveys_total - $surveys_done;
1108
            if (!empty($surveys_total)) {
1109
                $surveys_progress = round((( $surveys_done * 100 ) / $surveys_total), 2);
1110
            } else {
1111
                $surveys_progress = 0;
1112
            }
1113
1114
            //Forums
1115
            $forums_done = CourseManager::getCountForumPerUser(
1116
                $user['user_id'],
1117
                $course['real_id'],
1118
                $user['id_session']
1119
            );
1120
            $forums_left = $forums_total - $forums_done;
1121
            if (!empty($forums_total)) {
1122
                $forums_progress = round((( $forums_done * 100 ) / $forums_total), 2);
1123
            } else {
1124
                $forums_progress = 0;
1125
            }
1126
1127
            //Overall Total
1128
            $overall_total = ($course_description_progress + $exercises_progress + $forums_progress + $assignments_progress + $wiki_progress + $surveys_progress) / 6;
1129
1130
            $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>';
1131
            $linkForum = '<a href="' . api_get_path(WEB_CODE_PATH) . 'forum/index.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1132
            $linkWork = '<a href="' . api_get_path(WEB_CODE_PATH) . 'work/work.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1133
            $linkWiki = '<a href="' . api_get_path(WEB_CODE_PATH) . 'wiki/index.php?cidReq=' . $course['code'] . '&session_id=' . $user['id_session'] . '&action=statistics"> %s </a>';
1134
            $linkSurvey = '<a href="' . api_get_path(WEB_CODE_PATH) . 'survey/survey_list.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1135
1136
            $table[] = array(
1137
                'lastname' => $user[1],
1138
                'firstname' => $user[2],
1139
                'username' => $user[3],
1140
                #'profile'   => '',
1141
                'total' => round($overall_total, 2) . '%',
1142
                'courses' => sprintf($link, $course_description_progress . '%'),
1143
                'lessons' => sprintf($link, $lessons_progress . '%'),
1144
                'exercises' => sprintf($link, $exercises_progress . '%'),
1145
                'forums' => sprintf($link, $forums_progress . '%'),
1146
                'homeworks' => sprintf($link, $assignments_progress . '%'),
1147
                'wikis' => sprintf($link, $wiki_progress . '%'),
1148
                'surveys' => sprintf($link, $surveys_progress . '%'),
1149
                //course description
1150
                'course_description_progress' => $course_description_progress . '%',
1151
                //lessons
1152
                'lessons_total' => sprintf($link, $lessons_total),
1153
                'lessons_done' => sprintf($link, $lessons_done),
1154
                'lessons_left' => sprintf($link, $lessons_left),
1155
                'lessons_progress' => sprintf($link, $lessons_progress . '%'),
1156
                //exercises
1157
                'exercises_total' => sprintf($link, $exercises_total),
1158
                'exercises_done' => sprintf($link, $exercises_done),
1159
                'exercises_left' => sprintf($link, $exercises_left),
1160
                'exercises_progress' => sprintf($link, $exercises_progress . '%'),
1161
                //forums
1162
                'forums_total' => sprintf($linkForum, $forums_total),
1163
                'forums_done' => sprintf($linkForum, $forums_done),
1164
                'forums_left' => sprintf($linkForum, $forums_left),
1165
                'forums_progress' => sprintf($linkForum, $forums_progress . '%'),
1166
                //assignments
1167
                'assignments_total' => sprintf($linkWork, $assignments_total),
1168
                'assignments_done' => sprintf($linkWork, $assignments_done),
1169
                'assignments_left' => sprintf($linkWork, $assignments_left),
1170
                'assignments_progress' => sprintf($linkWork, $assignments_progress . '%'),
1171
                //wiki
1172
                'wiki_total' => sprintf($linkWiki, $wiki_total),
1173
                'wiki_revisions' => sprintf($linkWiki, $wiki_revisions),
1174
                'wiki_read' => sprintf($linkWiki, $wiki_read),
1175
                'wiki_unread' => sprintf($linkWiki, $wiki_unread),
1176
                'wiki_progress' => sprintf($linkWiki, $wiki_progress . '%'),
1177
                //survey
1178
                'surveys_total' => sprintf($linkSurvey, $surveys_total),
1179
                'surveys_done' => sprintf($linkSurvey, $surveys_done),
1180
                'surveys_left' => sprintf($linkSurvey, $surveys_left),
1181
                'surveys_progress' => sprintf($linkSurvey, $surveys_progress . '%'),
1182
            );
1183
        }
1184
1185
        return $table;
1186
    }
1187
1188
    /**
1189
     * @return int
1190
     */
1191 View Code Duplication
    public static function get_number_of_tracking_access_overview()
1192
    {
1193
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1194
        $sql = "SELECT COUNT(course_access_id) count FROM $table";
1195
        $result = Database::query($sql);
1196
        $row = Database::fetch_assoc($result);
1197
1198
        return $row['count'];
1199
    }
1200
1201
    /**
1202
     * Get the ip, total of clicks, login date and time logged in for all user, in one session
1203
     * @todo track_e_course_access table should have ip so we dont have to look for it in track_e_login
1204
     *
1205
     * @author César Perales <[email protected]>, Beeznest Team
1206
     * @version 1.9.6
1207
     */
1208
    public static function get_user_data_access_tracking_overview(
1209
        $sessionId,
1210
        $courseId,
1211
        $studentId = 0,
1212
        $profile = '',
1213
        $date_from = '',
1214
        $date_to = '',
1215
        $options
1216
    ) {
1217
        //escaping variables
1218
        $sessionId = intval($sessionId);
1219
        $courseId = intval($courseId);
1220
        $studentId = intval($studentId);
1221
        $profile = intval($profile);
1222
        $date_from = Database::escape_string($date_from);
1223
        $date_to = Database::escape_string($date_to);
1224
1225
        // database table definition
1226
        $user = Database::get_main_table(TABLE_MAIN_USER);
1227
        $course = Database::get_main_table(TABLE_MAIN_COURSE);
1228
        $track_e_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
1229
        $track_e_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1230
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
1231
1232
        global $export_csv;
1233
        if ($export_csv) {
1234
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
1235
        } else {
1236
            $is_western_name_order = api_is_western_name_order();
1237
        }
1238
1239
        $where = null;
1240
        if (isset($sessionId) && !empty($sessionId)) {
1241
            $where = sprintf(" WHERE a.session_id = %d", $sessionId);
1242
        }
1243
        if (isset($courseId) && !empty($courseId)) {
1244
            $where .= sprintf(" AND c.id = %d", $courseId);
1245
        }
1246
        if (isset($studentId) && !empty($studentId)) {
1247
            $where .= sprintf(" AND u.user_id = %d", $studentId);
1248
        }
1249
        if (isset($profile) && !empty($profile)) {
1250
            $where .= sprintf(" AND u.status = %d", $profile);
1251
        }
1252
        if (!empty($date_to) && !empty($date_from)) {
1253
            $where .= sprintf(
1254
                " AND a.login_course_date >= '%s 00:00:00'
1255
                 AND a.login_course_date <= '%s 23:59:59'",
1256
                $date_from,
1257
                $date_to
1258
            );
1259
        }
1260
1261
        $limit = null;
1262
        if (!empty($options['limit'])) {
1263
            $limit = " LIMIT " . $options['limit'];
1264
        }
1265
1266
        if (!empty($options['where'])) {
1267
            $where .= ' '.$options['where'];
1268
        }
1269
1270
        $order = null;
1271
        if (!empty($options['order'])) {
1272
            $order = " ORDER BY " . $options['order'];
1273
        }
1274
1275
        //TODO add course name
1276
        $sql = "SELECT
1277
                a.login_course_date ,
1278
                u.username ,
1279
                " . ($is_western_name_order ? "
1280
                    u.firstname,
1281
                    u.lastname,
1282
                    " : "
1283
                    u.lastname,
1284
                    u.firstname,
1285
                ") . "
1286
                a.logout_course_date,
1287
                a.counter,
1288
                c.title,
1289
                c.code,
1290
                u.user_id,
1291
                a.session_id
1292
            FROM $track_e_course_access a
1293
            INNER JOIN $user u ON a.user_id = u.user_id
1294
            INNER JOIN $course c ON a.c_id = c.id
1295
            $where $order $limit";
1296
        $result = Database::query(sprintf($sql, $sessionId, $courseId));
1297
1298
        $data = array();
1299
        while ($user = Database::fetch_assoc($result)) {
1300
            $data[] = $user;
1301
        }
1302
1303
        //foreach
1304
        foreach ($data as $key => $info) {
1305
            $sql = "SELECT
1306
                    name
1307
                    FROM $sessionTable
1308
                    WHERE
1309
                    id = {$info['session_id']}";
1310
            $result = Database::query($sql);
1311
            $session = Database::fetch_assoc($result);
1312
1313
            // building array to display
1314
            $return[] = array(
1315
                'user_id' => $info['user_id'],
1316
                'logindate' => $info['login_course_date'],
1317
                'username' => $info['username'],
1318
                'firstname' => $info['firstname'],
1319
                'lastname' => $info['lastname'],
1320
                'clicks' => $info['counter'], //+ $clicks[$info['user_id']],
1321
                'ip' => '',
1322
                'timeLoggedIn' => gmdate("H:i:s", strtotime($info['logout_course_date']) - strtotime($info['login_course_date'])),
1323
                'session' => $session['name'],
1324
            );
1325
        }
1326
1327
        foreach ($return as $key => $info) {
1328
            //Search for ip, we do less querys if we iterate the final array
1329
            $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
1330
            $result = Database::query($sql);
1331
            $ip = Database::fetch_assoc($result);
1332
            //if no ip founded, we search the closest higher ip
1333
            if (empty($ip['user_ip'])) {
1334
                $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
1335
                $result = Database::query($sql);
1336
                $ip = Database::fetch_assoc($result);
1337
            }
1338
            #add ip to final array
1339
            $return[$key]['ip'] = $ip['user_ip'];
1340
        }
1341
1342
        return $return;
1343
    }
1344
1345
    /**
1346
     * Creates a new course code based in given code
1347
     *
1348
     * @param string	$session_name
1349
     * <code>
1350
     * $wanted_code = 'curse' if there are in the DB codes like curse1 curse2 the function will return: course3
1351
     * if the course code doest not exist in the DB the same course code will be returned
1352
     * </code>
1353
     * @return string	wanted unused code
1354
     */
1355
    public static function generateNextSessionName($session_name)
1356
    {
1357
        $session_name_ok = !self::session_name_exists($session_name);
1358 View Code Duplication
        if (!$session_name_ok) {
1359
            $table = Database::get_main_table(TABLE_MAIN_SESSION);
1360
            $session_name = Database::escape_string($session_name);
1361
            $sql = "SELECT count(*) as count FROM $table
1362
                    WHERE name LIKE '$session_name%'";
1363
            $result = Database::query($sql);
1364
            if (Database::num_rows($result) > 0) {
1365
                $row = Database::fetch_array($result);
1366
                $count = $row['count'] + 1;
1367
                $session_name = $session_name . '_' . $count;
1368
                $result = self::session_name_exists($session_name);
1369
                if (!$result) {
1370
                    return $session_name;
1371
                }
1372
            }
1373
            return false;
1374
        }
1375
1376
        return $session_name;
1377
    }
1378
1379
    /**
1380
     * Edit a session
1381
     * @author Carlos Vargas from existing code
1382
     * @param integer   $id Session primary key
1383
     * @param string    $name
1384
     * @param string    $startDate
1385
     * @param string    $endDate
1386
     * @param string    $displayStartDate
1387
     * @param string    $displayEndDate
1388
     * @param string    $coachStartDate
1389
     * @param string    $coachEndDate
1390
     * @param integer   $coachId
1391
     * @param integer   $sessionCategoryId
1392
     * @param int       $visibility
1393
     * @param string    $description
1394
     * @param int       $showDescription
1395
     * @param int       $duration
1396
     * @param array     $extraFields
1397
     * @param int       $sessionAdminId
1398
     * @param boolean $sendSubscriptionNotification Optional.
1399
     *          Whether send a mail notification to users being subscribed
1400
     * @return mixed
1401
     */
1402
    public static function edit_session(
1403
        $id,
1404
        $name,
1405
        $startDate,
1406
        $endDate,
1407
        $displayStartDate,
1408
        $displayEndDate,
1409
        $coachStartDate,
1410
        $coachEndDate,
1411
        $coachId,
1412
        $sessionCategoryId,
1413
        $visibility,
1414
        $description = null,
1415
        $showDescription = 0,
1416
        $duration = null,
1417
        $extraFields = array(),
1418
        $sessionAdminId = 0,
1419
        $sendSubscriptionNotification = false
1420
    ) {
1421
        $coachId = intval($coachId);
1422
        $sessionCategoryId = intval($sessionCategoryId);
1423
        $visibility = intval($visibility);
1424
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1425
1426
        if (empty($name)) {
1427
            Display::addFlash(
1428
                Display::return_message(get_lang('SessionNameIsRequired'), 'warning')
1429
            );
1430
1431
            return false;
1432
        } elseif (empty($coachId)) {
1433
            Display::addFlash(
1434
                Display::return_message(get_lang('CoachIsRequired'), 'warning')
1435
            );
1436
1437
            return false;
1438
        } elseif (!empty($startDate) && !api_is_valid_date($startDate, 'Y-m-d H:i') && !api_is_valid_date($startDate, 'Y-m-d H:i:s')) {
1439
            Display::addFlash(
1440
                Display::return_message(get_lang('InvalidStartDate'), 'warning')
1441
            );
1442
1443
            return false;
1444
        } elseif (!empty($endDate) && !api_is_valid_date($endDate, 'Y-m-d H:i') && !api_is_valid_date($endDate, 'Y-m-d H:i:s')) {
1445
            Display::addFlash(
1446
                Display::return_message(get_lang('InvalidEndDate'), 'warning')
1447
            );
1448
1449
            return false;
1450
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
1451
            Display::addFlash(
1452
                Display::return_message(get_lang('StartDateShouldBeBeforeEndDate'), 'warning')
1453
            );
1454
1455
            return false;
1456
        } else {
1457
            $sessionInfo = self::get_session_by_name($name);
1458
            $exists = false;
1459
1460
            if (!empty($sessionInfo)) {
1461
                if ($sessionInfo['id'] != $id) {
1462
                    $exists = true;
1463
                }
1464
            }
1465
1466
            if ($exists) {
1467
                Display::addFlash(
1468
                    Display::return_message(get_lang('SessionNameAlreadyExists'), 'warning')
1469
                );
1470
1471
                return false;
1472
            } else {
1473
                $values = [
1474
                    'name' => $name,
1475
                    'duration' => $duration,
1476
                    'id_coach' => $coachId,
1477
                    'description'=> $description,
1478
                    'show_description' => intval($showDescription),
1479
                    'visibility' => $visibility,
1480
                    'send_subscription_notification' => $sendSubscriptionNotification,
1481
                    'access_start_date' => null,
1482
                    'access_end_date' => null,
1483
                    'display_start_date' => null,
1484
                    'display_end_date' => null,
1485
                    'coach_access_start_date' => null,
1486
                    'coach_access_end_date' => null
1487
                ];
1488
1489
                if (!empty($sessionAdminId)) {
1490
                    $values['session_admin_id'] = $sessionAdminId;
1491
                }
1492
1493
                if (!empty($startDate)) {
1494
                    $values['access_start_date'] = api_get_utc_datetime($startDate);
1495
                }
1496
1497
                if (!empty($endDate)) {
1498
                    $values['access_end_date'] = api_get_utc_datetime($endDate);
1499
                }
1500
1501
                if (!empty($displayStartDate)) {
1502
                    $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
1503
                }
1504
1505
                if (!empty($displayEndDate)) {
1506
                    $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
1507
                }
1508
1509
                if (!empty($coachStartDate)) {
1510
                    $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
1511
                }
1512
                if (!empty($coachEndDate)) {
1513
                    $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
1514
                }
1515
1516
                if (!empty($sessionCategoryId)) {
1517
                    $values['session_category_id'] = $sessionCategoryId;
1518
                } else {
1519
                    $values['session_category_id'] = null;
1520
                }
1521
1522
                Database::update(
1523
                    $tbl_session,
1524
                    $values,
1525
                    array('id = ?' => $id)
1526
                );
1527
1528
                if (!empty($extraFields)) {
1529
                    $extraFields['item_id'] = $id;
1530
                    $sessionFieldValue = new ExtraFieldValue('session');
1531
                    $sessionFieldValue->saveFieldValues($extraFields);
1532
                }
1533
1534
                return $id;
1535
            }
1536
        }
1537
    }
1538
1539
    /**
1540
     * Delete session
1541
     * @author Carlos Vargas  from existing code
1542
     * @param	array	$id_checked an array to delete sessions
1543
     * @param   boolean  $from_ws optional, true if the function is called
1544
     * by a webservice, false otherwise.
1545
     * @return	void	Nothing, or false on error
1546
     * */
1547
    public static function delete($id_checked, $from_ws = false)
1548
    {
1549
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1550
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1551
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1552
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1553
        $tbl_url_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
1554
        $tbl_item_properties = Database::get_course_table(TABLE_ITEM_PROPERTY);
1555
        $tbl_student_publication = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1556
        $tbl_student_publication_assignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1557
        $userGroupSessionTable = Database::get_main_table(TABLE_USERGROUP_REL_SESSION);
1558
1559
        $ticket = Database::get_main_table(TABLE_TICKET_TICKET);
1560
        $em = Database::getManager();
1561
1562
        $userId = api_get_user_id();
1563
1564
        /** @var \Chamilo\CoreBundle\Entity\Repository\SequenceRepository $repo */
1565
        $repo = Database::getManager()->getRepository('ChamiloCoreBundle:SequenceResource');
1566
        $sequenceResourse = $repo->findRequirementForResource(
1567
            $id_checked,
1568
            \Chamilo\CoreBundle\Entity\SequenceResource::SESSION_TYPE
1569
        );
1570
1571
        if ($sequenceResourse) {
1572
            Display::addFlash(Display::return_message(get_lang('ThereIsASequenceResourceLinkedToThisSessionYouNeedToDeleteItFirst'), 'error'));
1573
            return false;
1574
        }
1575
1576
        if (is_array($id_checked)) {
1577
            foreach ($id_checked as $sessionId) {
1578
                self::delete($sessionId);
1579
            }
1580
        } else {
1581
            $id_checked = intval($id_checked);
1582
        }
1583
1584
        if (self::allowed($id_checked) && !$from_ws) {
0 ignored issues
show
Bug introduced by
It seems like $id_checked defined by parameter $id_checked on line 1547 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...
1585
            $qb = $em
1586
                ->createQuery('
1587
                    SELECT s.sessionAdminId FROM ChamiloCoreBundle:Session s
1588
                    WHERE s.id = ?1
1589
                ')
1590
                ->setParameter(1, $id_checked);
1591
1592
            $res = $qb->getSingleScalarResult();
1593
1594
            if ($res != $userId && !api_is_platform_admin()) {
1595
                api_not_allowed(true);
1596
            }
1597
        }
1598
1599
        // Delete documents inside a session
1600
        $courses = self::getCoursesInSession($id_checked);
1601
        foreach ($courses as $courseId) {
1602
            $courseInfo = api_get_course_info_by_id($courseId);
1603
            DocumentManager::deleteDocumentsFromSession($courseInfo, $id_checked);
0 ignored issues
show
Bug introduced by
It seems like $id_checked defined by parameter $id_checked on line 1547 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...
1604
1605
            $works = Database::select(
1606
                '*',
1607
                $tbl_student_publication,
1608
                [
1609
                    'where' => ['session_id = ? AND c_id = ?' => [$id_checked, $courseId]]
1610
                ]
1611
            );
1612
1613
            $currentCourseRepositorySys = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/';
1614
1615
            foreach ($works as $index => $work) {
1616
                if ($work['filetype'] = 'folder') {
1617
                    Database::query("DELETE FROM $tbl_student_publication_assignment WHERE publication_id = $index");
1618
                }
1619
                my_delete($currentCourseRepositorySys.'/'.$work['url']);
1620
            }
1621
        }
1622
1623
        // Class
1624
        $sql = "DELETE FROM $userGroupSessionTable
1625
                WHERE session_id IN($id_checked)";
1626
        Database::query($sql);
1627
1628
        Database::query("DELETE FROM $tbl_student_publication WHERE session_id IN($id_checked)");
1629
        Database::query("DELETE FROM $tbl_session_rel_course WHERE session_id IN($id_checked)");
1630
        Database::query("DELETE FROM $tbl_session_rel_course_rel_user WHERE session_id IN($id_checked)");
1631
        Database::query("DELETE FROM $tbl_session_rel_user WHERE session_id IN($id_checked)");
1632
        Database::query("DELETE FROM $tbl_item_properties WHERE session_id IN ($id_checked)");
1633
        Database::query("DELETE FROM $tbl_url_session WHERE session_id IN($id_checked)");
1634
1635
        $sql = "UPDATE $ticket SET session_id = NULL WHERE session_id IN ($id_checked)";
1636
        Database::query($sql);
1637
1638
        $sql = "DELETE FROM $tbl_session WHERE id IN ($id_checked)";
1639
        Database::query($sql);
1640
1641
        $extraFieldValue = new ExtraFieldValue('session');
1642
        $extraFieldValue->deleteValuesByItem($id_checked);
0 ignored issues
show
Bug introduced by
It seems like $id_checked defined by parameter $id_checked on line 1547 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...
1643
1644
        $repo->deleteResource(
1645
            $id_checked,
0 ignored issues
show
Bug introduced by
It seems like $id_checked defined by parameter $id_checked on line 1547 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...
1646
            \Chamilo\CoreBundle\Entity\SequenceResource::SESSION_TYPE
1647
        );
1648
1649
        // Add event to system log
1650
        Event::addEvent(
1651
            LOG_SESSION_DELETE,
1652
            LOG_SESSION_ID,
1653
            $id_checked,
1654
            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...
1655
            $userId
1656
        );
1657
1658
        return true;
1659
    }
1660
1661
    /**
1662
     * @param int $id promotion id
1663
     *
1664
     * @return bool
1665
     */
1666 View Code Duplication
    public static function clear_session_ref_promotion($id)
1667
    {
1668
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1669
        $id = intval($id);
1670
        $sql = "UPDATE $tbl_session 
1671
                SET promotion_id = 0
1672
                WHERE promotion_id = $id";
1673
        if (Database::query($sql)) {
1674
            return true;
1675
        } else {
1676
            return false;
1677
        }
1678
    }
1679
1680
    /**
1681
     * Subscribes students to the given session and optionally (default) unsubscribes previous users
1682
     *
1683
     * @author Carlos Vargas from existing code
1684
     * @author Julio Montoya. Cleaning code.
1685
     * @param int $id_session
1686
     * @param array $user_list
1687
     * @param int $session_visibility
1688
     * @param bool $empty_users
1689
     * @return bool
1690
     */
1691
    public static function subscribe_users_to_session(
1692
        $id_session,
1693
        $user_list,
1694
        $session_visibility = SESSION_VISIBLE_READ_ONLY,
1695
        $empty_users = true
1696
    ) {
1697
        if ($id_session != strval(intval($id_session))) {
1698
            return false;
1699
        }
1700
1701
        foreach ($user_list as $intUser) {
1702
            if ($intUser != strval(intval($intUser))) {
1703
                return false;
1704
            }
1705
        }
1706
1707
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1708
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1709
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1710
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1711
1712
        $entityManager = Database::getManager();
1713
        $session = $entityManager->find('ChamiloCoreBundle:Session', $id_session);
1714
1715
        // from function parameter
1716
        if (empty($session_visibility)) {
1717
            $session_visibility = $session->getVisibility();
1718
            //default status loaded if empty
1719
            // by default readonly 1
1720
            if (empty($session_visibility)) {
1721
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
1722
            }
1723
        } else {
1724
            if (!in_array($session_visibility, array(SESSION_VISIBLE_READ_ONLY, SESSION_VISIBLE, SESSION_INVISIBLE))) {
1725
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
1726
            }
1727
        }
1728
1729
        $sql = "SELECT user_id FROM $tbl_session_rel_course_rel_user
1730
                WHERE session_id = $id_session AND status = 0";
1731
        $result = Database::query($sql);
1732
        $existingUsers = array();
1733
        while ($row = Database::fetch_array($result)) {
1734
            $existingUsers[] = $row['user_id'];
1735
        }
1736
1737
        $sql = "SELECT c_id FROM $tbl_session_rel_course
1738
                WHERE session_id = $id_session";
1739
        $result = Database::query($sql);
1740
        $course_list = array();
1741
        while ($row = Database::fetch_array($result)) {
1742
            $course_list[] = $row['c_id'];
1743
        }
1744
1745
        if ($session->getSendSubscriptionNotification() &&
1746
            is_array($user_list)
1747
        ) {
1748
            // Sending emails only
1749
            foreach ($user_list as $user_id) {
1750
                if (in_array($user_id, $existingUsers)) {
1751
                    continue;
1752
                }
1753
1754
                $tplSubject = new Template(null, false, false, false, false, false);
1755
                $layoutSubject = $tplSubject->get_template(
1756
                    'mail/subject_subscription_to_session_confirmation.tpl'
1757
                );
1758
                $subject = $tplSubject->fetch($layoutSubject);
1759
1760
                $user_info = api_get_user_info($user_id);
1761
1762
                $tplContent = new Template(null, false, false, false, false, false);
1763
                // Variables for default template
1764
                $tplContent->assign(
1765
                    'complete_name',
1766
                    stripslashes($user_info['complete_name'])
1767
                );
1768
                $tplContent->assign('session_name', $session->getName());
1769
                $tplContent->assign(
1770
                    'session_coach',
1771
                    $session->getGeneralCoach()->getCompleteName()
1772
                );
1773
                $layoutContent = $tplContent->get_template(
1774
                    'mail/content_subscription_to_session_confirmation.tpl'
1775
                );
1776
                $content = $tplContent->fetch($layoutContent);
1777
1778
                api_mail_html(
1779
                    $user_info['complete_name'],
1780
                    $user_info['mail'],
1781
                    $subject,
1782
                    $content,
1783
                    api_get_person_name(
1784
                        api_get_setting('administratorName'),
1785
                        api_get_setting('administratorSurname')
1786
                    ),
1787
                    api_get_setting('emailAdministrator')
1788
                );
1789
            }
1790
        }
1791
1792
        foreach ($course_list as $courseId) {
1793
            // for each course in the session
1794
            $nbr_users = 0;
1795
            $courseId = intval($courseId);
1796
1797
            $sql = "SELECT DISTINCT user_id
1798
                    FROM $tbl_session_rel_course_rel_user
1799
                    WHERE
1800
                        session_id = $id_session AND
1801
                        c_id = $courseId AND
1802
                        status = 0
1803
                    ";
1804
            $result = Database::query($sql);
1805
            $existingUsers = array();
1806
            while ($row = Database::fetch_array($result)) {
1807
                $existingUsers[] = $row['user_id'];
1808
            }
1809
1810
            // Delete existing users
1811 View Code Duplication
            if ($empty_users) {
1812
                foreach ($existingUsers as $existing_user) {
1813
                    if (!in_array($existing_user, $user_list)) {
1814
                        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
1815
                                WHERE
1816
                                    session_id = $id_session AND
1817
                                    c_id = $courseId AND
1818
                                    user_id = $existing_user AND
1819
                                    status = 0 ";
1820
                        $result = Database::query($sql);
1821
1822
                        Event::addEvent(
1823
                            LOG_SESSION_DELETE_USER_COURSE,
1824
                            LOG_USER_ID,
1825
                            $existing_user,
1826
                            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...
1827
                            api_get_user_id(),
1828
                            $courseId,
1829
                            $id_session
1830
                        );
1831
1832
                        if (Database::affected_rows($result)) {
1833
                            $nbr_users--;
1834
                        }
1835
                    }
1836
                }
1837
            }
1838
1839
            // Replace with this new function
1840
            // insert new users into session_rel_course_rel_user and ignore if they already exist
1841
1842
            foreach ($user_list as $enreg_user) {
1843 View Code Duplication
                if (!in_array($enreg_user, $existingUsers)) {
1844
                    $enreg_user = Database::escape_string($enreg_user);
1845
                    $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id, visibility, status)
1846
                            VALUES($id_session, $courseId, $enreg_user, $session_visibility, 0)";
1847
                    $result = Database::query($sql);
1848
1849
                    Event::addEvent(
1850
                        LOG_SESSION_ADD_USER_COURSE,
1851
                        LOG_USER_ID,
1852
                        $enreg_user,
1853
                        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...
1854
                        api_get_user_id(),
1855
                        $courseId,
1856
                        $id_session
1857
                    );
1858
1859
                    if (Database::affected_rows($result)) {
1860
1861
                        $nbr_users++;
1862
                    }
1863
                }
1864
            }
1865
1866
            // Count users in this session-course relation
1867
            $sql = "SELECT COUNT(user_id) as nbUsers
1868
                    FROM $tbl_session_rel_course_rel_user
1869
                    WHERE session_id = $id_session AND c_id = $courseId AND status<>2";
1870
            $rs = Database::query($sql);
1871
            list($nbr_users) = Database::fetch_array($rs);
1872
            // update the session-course relation to add the users total
1873
            $sql = "UPDATE $tbl_session_rel_course SET nbr_users = $nbr_users
1874
                    WHERE session_id = $id_session AND c_id = $courseId";
1875
            Database::query($sql);
1876
        }
1877
1878
        // Delete users from the session
1879
        if ($empty_users === true) {
1880
            $sql = "DELETE FROM $tbl_session_rel_user
1881
                    WHERE session_id = $id_session AND relation_type<>" . SESSION_RELATION_TYPE_RRHH . "";
1882
            Database::query($sql);
1883
        }
1884
1885
        // Insert missing users into session
1886
        $nbr_users = 0;
1887
1888
        foreach ($user_list as $enreg_user) {
1889
            $enreg_user = Database::escape_string($enreg_user);
1890
            $nbr_users++;
1891
            $sql = "INSERT IGNORE INTO $tbl_session_rel_user (relation_type, session_id, user_id, registered_at)
1892
                    VALUES (0, $id_session, $enreg_user, '" . api_get_utc_datetime() . "')";
1893
            Database::query($sql);
1894
        }
1895
1896
        // update number of users in the session
1897
        $nbr_users = count($user_list);
1898
        if ($empty_users) {
1899
            // update number of users in the session
1900
            $sql = "UPDATE $tbl_session SET nbr_users= $nbr_users
1901
                    WHERE id = $id_session ";
1902
            Database::query($sql);
1903
        } else {
1904
            $sql = "UPDATE $tbl_session SET nbr_users = nbr_users + $nbr_users
1905
                    WHERE id = $id_session";
1906
            Database::query($sql);
1907
        }
1908
    }
1909
1910
    /**
1911
     * Returns user list of the current users subscribed in the course-session
1912
     * @param int $sessionId
1913
     * @param array $courseInfo
1914
     * @param int $status
1915
     *
1916
     * @return array
1917
     */
1918
    public static function getUsersByCourseSession(
1919
        $sessionId,
1920
        $courseInfo,
1921
        $status = null
1922
    ) {
1923
        $sessionId = intval($sessionId);
1924
        $courseCode = $courseInfo['code'];
1925
        $courseId = $courseInfo['real_id'];
1926
1927
        if (empty($sessionId) || empty($courseCode)) {
1928
            return array();
1929
        }
1930
1931
        $statusCondition = null;
1932 View Code Duplication
        if (isset($status) && !is_null($status)) {
1933
            $status = intval($status);
1934
            $statusCondition = " AND status = $status";
1935
        }
1936
1937
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1938
1939
        $sql = "SELECT DISTINCT user_id
1940
                FROM $table
1941
                WHERE
1942
                    session_id = $sessionId AND
1943
                    c_id = $courseId
1944
                    $statusCondition
1945
                ";
1946
        $result = Database::query($sql);
1947
        $existingUsers = array();
1948
        while ($row = Database::fetch_array($result)) {
1949
            $existingUsers[] = $row['user_id'];
1950
        }
1951
1952
        return $existingUsers;
1953
    }
1954
1955
    /**
1956
     * Remove a list of users from a course-session
1957
     * @param array $userList
1958
     * @param int $sessionId
1959
     * @param array $courseInfo
1960
     * @param int $status
1961
     * @param bool $updateTotal
1962
     * @return bool
1963
     */
1964
    public static function removeUsersFromCourseSession(
1965
        $userList,
1966
        $sessionId,
1967
        $courseInfo,
1968
        $status = null,
1969
        $updateTotal = true
1970
    ) {
1971
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1972
        $tableSessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1973
        $sessionId = intval($sessionId);
1974
1975
        if (empty($sessionId) || empty($userList) || empty($courseInfo)) {
1976
            return false;
1977
        }
1978
1979
        is_array($courseInfo) ? $courseId = $courseInfo['real_id'] : $courseId = $courseInfo;
1980
1981
        $statusCondition = null;
1982 View Code Duplication
        if (isset($status) && !is_null($status)) {
1983
            $status = intval($status);
1984
            $statusCondition  = " AND status = $status";
1985
        }
1986
1987
        foreach ($userList as $userId) {
1988
            $userId = intval($userId);
1989
            $sql = "DELETE FROM $table
1990
                    WHERE
1991
                        session_id = $sessionId AND
1992
                        c_id = $courseId AND
1993
                        user_id = $userId
1994
                        $statusCondition
1995
                    ";
1996
            Database::query($sql);
1997
        }
1998
1999
        if ($updateTotal) {
2000
            // Count users in this session-course relation
2001
            $sql = "SELECT COUNT(user_id) as nbUsers
2002
                    FROM $table
2003
                    WHERE
2004
                        session_id = $sessionId AND
2005
                        c_id = $courseId AND
2006
                        status <> 2";
2007
            $result = Database::query($sql);
2008
            list($userCount) = Database::fetch_array($result);
2009
2010
            // update the session-course relation to add the users total
2011
            $sql = "UPDATE $tableSessionCourse
2012
                    SET nbr_users = $userCount
2013
                    WHERE
2014
                        session_id = $sessionId AND
2015
                        c_id = $courseId";
2016
            Database::query($sql);
2017
        }
2018
    }
2019
2020
    /**
2021
     * Subscribe a user to an specific course inside a session.
2022
     *
2023
     * @param array $user_list
2024
     * @param int $session_id
2025
     * @param string $course_code
2026
     * @param int $session_visibility
2027
     * @param bool $removeUsersNotInList
2028
     * @return bool
2029
     */
2030
    public static function subscribe_users_to_session_course(
2031
        $user_list,
2032
        $session_id,
2033
        $course_code,
2034
        $session_visibility = SESSION_VISIBLE_READ_ONLY,
2035
        $removeUsersNotInList = false
2036
    ) {
2037
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2038
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2039
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2040
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2041
2042
        if (empty($session_id) || empty($course_code)) {
2043
            return false;
2044
        }
2045
2046
        $session_id = intval($session_id);
2047
        $course_code = Database::escape_string($course_code);
2048
        $courseInfo = api_get_course_info($course_code);
2049
        $courseId = $courseInfo['real_id'];
2050
2051
        $session_visibility = intval($session_visibility);
2052
2053
        if ($removeUsersNotInList) {
2054
2055
            $currentUsers = self::getUsersByCourseSession($session_id, $courseInfo, 0);
2056
2057
            if (!empty($user_list)) {
2058
                $userToDelete = array_diff($currentUsers, $user_list);
2059
            } else {
2060
                $userToDelete = $currentUsers;
2061
            }
2062
2063
            if (!empty($userToDelete)) {
2064
                self::removeUsersFromCourseSession(
2065
                    $userToDelete,
2066
                    $session_id,
2067
                    $courseInfo,
2068
                    0,
2069
                    true
2070
                );
2071
            }
2072
        }
2073
2074
        $nbr_users = 0;
2075
        foreach ($user_list as $enreg_user) {
2076
            $enreg_user = intval($enreg_user);
2077
            // Checking if user exists in session - course - user table.
2078
            $sql = "SELECT count(user_id) as count
2079
                    FROM $tbl_session_rel_course_rel_user
2080
                    WHERE
2081
                        session_id = $session_id AND
2082
                        c_id = $courseId and
2083
                        user_id = $enreg_user ";
2084
            $result = Database::query($sql);
2085
            $count = 0;
2086
2087
            if (Database::num_rows($result) > 0) {
2088
                $row = Database::fetch_array($result, 'ASSOC');
2089
                $count = $row['count'];
2090
            }
2091
2092
            if ($count == 0) {
2093
                $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id, visibility)
2094
                        VALUES ($session_id, $courseId, $enreg_user, $session_visibility)";
2095
                $result = Database::query($sql);
2096
                if (Database::affected_rows($result)) {
2097
                    $nbr_users++;
2098
                }
2099
            }
2100
2101
            // Checking if user exists in session - user table.
2102
            $sql = "SELECT count(user_id) as count
2103
                    FROM $tbl_session_rel_user
2104
                    WHERE session_id = $session_id AND user_id = $enreg_user ";
2105
            $result = Database::query($sql);
2106
            $count = 0;
2107
2108
            if (Database::num_rows($result) > 0) {
2109
                $row = Database::fetch_array($result, 'ASSOC');
2110
                $count = $row['count'];
2111
            }
2112
2113 View Code Duplication
            if (empty($count)) {
2114
                // If user is not registered to a session then add it.
2115
                $sql = "INSERT IGNORE INTO $tbl_session_rel_user (session_id, user_id, registered_at)
2116
                        VALUES ($session_id, $enreg_user, '" . api_get_utc_datetime() . "')";
2117
                Database::query($sql);
2118
2119
                $sql = "UPDATE $tbl_session SET nbr_users = nbr_users + 1
2120
                        WHERE id = $session_id ";
2121
                Database::query($sql);
2122
            }
2123
        }
2124
2125
        // count users in this session-course relation
2126
        $sql = "SELECT COUNT(user_id) as nbUsers
2127
                FROM $tbl_session_rel_course_rel_user
2128
                WHERE session_id = $session_id AND c_id = $courseId AND status <> 2";
2129
        $rs = Database::query($sql);
2130
        list($nbr_users) = Database::fetch_array($rs);
2131
        // update the session-course relation to add the users total
2132
        $sql = "UPDATE $tbl_session_rel_course
2133
                SET nbr_users = $nbr_users
2134
                WHERE session_id = $session_id AND c_id = $courseId";
2135
        Database::query($sql);
2136
    }
2137
2138
    /**
2139
     * Unsubscribe user from session
2140
     *
2141
     * @param int Session id
2142
     * @param int User id
2143
     * @return bool True in case of success, false in case of error
2144
     */
2145
    public static function unsubscribe_user_from_session($session_id, $user_id)
2146
    {
2147
        $session_id = (int) $session_id;
2148
        $user_id = (int) $user_id;
2149
2150
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2151
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2152
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2153
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2154
2155
        $sql = "DELETE FROM $tbl_session_rel_user
2156
                WHERE
2157
                    session_id = $session_id AND
2158
                    user_id = $user_id AND
2159
                    relation_type <> " . SESSION_RELATION_TYPE_RRHH . "";
2160
        $result = Database::query($sql);
2161
        $return = Database::affected_rows($result);
2162
2163
        // Update number of users
2164
        $sql = "UPDATE $tbl_session
2165
                SET nbr_users = nbr_users - $return
2166
                WHERE id = $session_id ";
2167
        Database::query($sql);
2168
2169
        // Get the list of courses related to this session
2170
        $course_list = self::get_course_list_by_session_id($session_id);
2171
2172
        if (!empty($course_list)) {
2173
            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...
2174
                $courseId = $course['id'];
2175
                // Delete user from course
2176
                $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2177
                        WHERE session_id = $session_id AND c_id = $courseId AND user_id = $user_id";
2178
                $result = Database::query($sql);
2179
2180
                Event::addEvent(
2181
                    LOG_SESSION_DELETE_USER_COURSE,
2182
                    LOG_USER_ID,
2183
                    $user_id,
2184
                    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...
2185
                    api_get_user_id(),
2186
                    $courseId,
2187
                    $session_id
2188
                );
2189
2190
                if (Database::affected_rows($result)) {
2191
                    // Update number of users in this relation
2192
                    $sql = "UPDATE $tbl_session_rel_course SET 
2193
                            nbr_users = nbr_users - 1
2194
                            WHERE session_id = $session_id AND c_id = $courseId";
2195
                    Database::query($sql);
2196
                }
2197
            }
2198
        }
2199
2200
        return true;
2201
    }
2202
2203
    /**
2204
     * Subscribes courses to the given session and optionally (default)
2205
     * unsubscribe previous users
2206
     * @author Carlos Vargas from existing code
2207
     * @param	int		$sessionId
2208
     * @param	array	$courseList List of courses int ids
2209
     * @param	bool	$removeExistingCoursesWithUsers Whether to unsubscribe
2210
     * existing courses and users (true, default) or not (false)
2211
     * @param bool $copyEvaluation from base course to session course
2212
     * @return	void	Nothing, or false on error
2213
     * */
2214
    public static function add_courses_to_session(
2215
        $sessionId,
2216
        $courseList,
2217
        $removeExistingCoursesWithUsers = true,
2218
        $copyEvaluation = false
2219
    ) {
2220
        $sessionId = intval($sessionId);
2221
2222
        if (empty($sessionId) || empty($courseList)) {
2223
            return false;
2224
        }
2225
2226
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2227
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2228
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2229
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2230
2231
        // Get list of courses subscribed to this session
2232
        $sql = "SELECT c_id
2233
                FROM $tbl_session_rel_course
2234
                WHERE session_id = $sessionId";
2235
        $rs = Database::query($sql);
2236
        $existingCourses = Database::store_result($rs);
2237
        $nbr_courses = count($existingCourses);
2238
2239
        // Get list of users subscribed to this session
2240
        $sql = "SELECT user_id
2241
                FROM $tbl_session_rel_user
2242
                WHERE
2243
                    session_id = $sessionId AND
2244
                    relation_type<>" . SESSION_RELATION_TYPE_RRHH;
2245
        $result = Database::query($sql);
2246
        $user_list = Database::store_result($result);
2247
2248
        // Remove existing courses from the session.
2249
        if ($removeExistingCoursesWithUsers === true && !empty($existingCourses)) {
2250
            foreach ($existingCourses as $existingCourse) {
2251
                if (!in_array($existingCourse['c_id'], $courseList)) {
2252
2253
                    $sql = "DELETE FROM $tbl_session_rel_course
2254
                            WHERE
2255
                                c_id = " . $existingCourse['c_id'] . " AND
2256
                                session_id = $sessionId";
2257
                    Database::query($sql);
2258
2259
                    $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2260
                            WHERE
2261
                                c_id = ".$existingCourse['c_id']." AND
2262
                                session_id = $sessionId";
2263
                    Database::query($sql);
2264
2265
                    Event::addEvent(
2266
                        LOG_SESSION_DELETE_COURSE,
2267
                        LOG_COURSE_ID,
2268
                        $existingCourse['c_id'],
2269
                        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...
2270
                        api_get_user_id(),
2271
                        $existingCourse['c_id'],
2272
                        $sessionId
2273
                    );
2274
2275
                    CourseManager::remove_course_ranking(
2276
                        $existingCourse['c_id'],
2277
                        $sessionId
2278
                    );
2279
2280
                    $nbr_courses--;
2281
                }
2282
            }
2283
        }
2284
2285
        // Pass through the courses list we want to add to the session
2286
        foreach ($courseList as $courseId) {
2287
            $courseInfo = api_get_course_info_by_id($courseId);
2288
2289
            // If course doesn't exists continue!
2290
            if (empty($courseInfo)) {
2291
                continue;
2292
            }
2293
2294
            $exists = false;
2295
            // check if the course we want to add is already subscribed
2296
            foreach ($existingCourses as $existingCourse) {
2297
                if ($courseId == $existingCourse['c_id']) {
2298
                    $exists = true;
2299
                }
2300
            }
2301
2302
            if (!$exists) {
2303
                // Copy gradebook categories and links (from base course)
2304
                // to the new course session
2305
                if ($copyEvaluation) {
2306
                    $cats = Category::load(null, null, $courseInfo['code']);
2307
                    if (!empty($cats)) {
2308
                        $sessionCategory = Category:: load(
2309
                            null,
2310
                            null,
2311
                            $courseInfo['code'],
2312
                            null,
2313
                            null,
2314
                            $sessionId,
2315
                            false
2316
                        );
2317
2318
                        // @todo remove commented code
2319
                        if (empty($sessionCategory)) {
2320
                            // There is no category for this course+session, so create one
2321
                            $cat = new Category();
2322
                            $sessionName = api_get_session_name($sessionId);
2323
                            $cat->set_name($courseInfo['code'].' - '.get_lang('Session').' '.$sessionName);
2324
                            $cat->set_session_id($sessionId);
2325
                            $cat->set_course_code($courseInfo['code']);
2326
                            $cat->set_description(null);
2327
                            //$cat->set_user_id($stud_id);
2328
                            $cat->set_parent_id(0);
2329
                            $cat->set_weight(100);
2330
                            $cat->set_visible(0);
2331
                            $cat->set_certificate_min_score(75);
2332
                            $cat->add();
2333
                            $sessionGradeBookCategoryId = $cat->get_id();
2334
                        } else {
2335
                            if (!empty($sessionCategory[0])) {
2336
                                $sessionGradeBookCategoryId = $sessionCategory[0]->get_id();
2337
                            }
2338
                        }
2339
2340
                        $categoryIdList = [];
2341
                        /** @var Category $cat */
2342
                        foreach ($cats as $cat) {
2343
                            $categoryIdList[$cat->get_id()] = $cat->get_id();
2344
                        }
2345
2346
                        $newCategoryIdList = [];
2347
                        foreach ($cats as $cat) {
2348
                            $links = $cat->get_links(
2349
                                null,
2350
                                false,
2351
                                $courseInfo['code'],
2352
                                0
2353
                            );
2354
2355
                            //$cat->set_session_id($sessionId);
2356
                            //$oldCategoryId = $cat->get_id();
2357
                            //$newId = $cat->add();
2358
                            //$newCategoryIdList[$oldCategoryId] = $newId;
2359
                            //$parentId = $cat->get_parent_id();
2360
2361
                            /*if (!empty($parentId)) {
2362
                                $newParentId = $newCategoryIdList[$parentId];
2363
                                $cat->set_parent_id($newParentId);
2364
                                $cat->save();
2365
                            }*/
2366
2367
                            if (!empty($links)) {
2368
                                /** @var AbstractLink $link */
2369
                                foreach ($links as $link) {
2370
                                    //$newCategoryId = $newCategoryIdList[$link->get_category_id()];
2371
                                    $link->set_category_id(
2372
                                        $sessionGradeBookCategoryId
2373
                                    );
2374
                                    $link->add();
2375
                                }
2376
                            }
2377
2378
                            $evaluationList = $cat->get_evaluations(
2379
                                null,
2380
                                false,
2381
                                $courseInfo['code'],
2382
                                0
2383
                            );
2384
2385
                            if (!empty($evaluationList)) {
2386
                                /** @var Evaluation $evaluation */
2387
                                foreach ($evaluationList as $evaluation) {
2388
                                    //$evaluationId = $newCategoryIdList[$evaluation->get_category_id()];
2389
                                    $evaluation->set_category_id(
2390
                                        $sessionGradeBookCategoryId
2391
                                    );
2392
                                    $evaluation->add();
2393
                                }
2394
                            }
2395
                        }
2396
2397
                        // Create
2398
                        DocumentManager::generateDefaultCertificate(
2399
                            $courseInfo,
2400
                            true,
2401
                            $sessionId
2402
                        );
2403
                    }
2404
                }
2405
2406
                // If the course isn't subscribed yet
2407
                $sql = "INSERT INTO $tbl_session_rel_course (session_id, c_id, nbr_users, position)
2408
                        VALUES ($sessionId, $courseId, 0, 0)";
2409
                Database::query($sql);
2410
2411
                Event::addEvent(
2412
                    LOG_SESSION_ADD_COURSE,
2413
                    LOG_COURSE_ID,
2414
                    $courseId,
2415
                    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...
2416
                    api_get_user_id(),
2417
                    $courseId,
2418
                    $sessionId
2419
                );
2420
2421
                // We add the current course in the existing courses array,
2422
                // to avoid adding another time the current course
2423
                $existingCourses[] = array('c_id' => $courseId);
2424
                $nbr_courses++;
2425
2426
                // subscribe all the users from the session to this course inside the session
2427
                $nbr_users = 0;
2428 View Code Duplication
                foreach ($user_list as $enreg_user) {
2429
                    $enreg_user_id = intval($enreg_user['user_id']);
2430
                    $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id)
2431
                            VALUES ($sessionId, $courseId, $enreg_user_id)";
2432
                    $result = Database::query($sql);
2433
2434
                    Event::addEvent(
2435
                        LOG_SESSION_ADD_USER_COURSE,
2436
                        LOG_USER_ID,
2437
                        $enreg_user_id,
2438
                        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...
2439
                        api_get_user_id(),
2440
                        $courseId,
2441
                        $sessionId
2442
                    );
2443
2444
                    if (Database::affected_rows($result)) {
2445
                        $nbr_users++;
2446
                    }
2447
                }
2448
                $sql = "UPDATE $tbl_session_rel_course
2449
                        SET nbr_users = $nbr_users
2450
                        WHERE session_id = $sessionId AND c_id = $courseId";
2451
                Database::query($sql);
2452
            }
2453
        }
2454
2455
        $sql = "UPDATE $tbl_session
2456
                SET nbr_courses = $nbr_courses
2457
                WHERE id = $sessionId";
2458
        Database::query($sql);
2459
    }
2460
2461
    /**
2462
     * Unsubscribe course from a session
2463
     *
2464
     * @param int $session_id
2465
     * @param int $course_id
2466
     * @return bool True in case of success, false otherwise
2467
     */
2468
    public static function unsubscribe_course_from_session($session_id, $course_id)
2469
    {
2470
        $session_id = (int) $session_id;
2471
        $course_id = (int) $course_id;
2472
2473
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2474
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2475
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2476
2477
        // Get course code
2478
        $course_code = CourseManager::get_course_code_from_course_id($course_id);
2479
        $course_id = intval($course_id);
2480
2481
        if (empty($course_code)) {
2482
            return false;
2483
        }
2484
2485
        // Unsubscribe course
2486
        $sql = "DELETE FROM $tbl_session_rel_course
2487
                WHERE c_id = $course_id AND session_id = $session_id";
2488
        $result = Database::query($sql);
2489
        $nb_affected = Database::affected_rows($result);
2490
2491
        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2492
                WHERE c_id = $course_id AND session_id = $session_id";
2493
        Database::query($sql);
2494
2495
        Event::addEvent(
2496
            LOG_SESSION_DELETE_COURSE,
2497
            LOG_COURSE_ID,
2498
            $course_id,
2499
            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...
2500
            api_get_user_id(),
2501
            $course_id,
2502
            $session_id
2503
        );
2504
2505
        if ($nb_affected > 0) {
2506
            // Update number of courses in the session
2507
            $sql = "UPDATE $tbl_session SET nbr_courses= nbr_courses - $nb_affected
2508
                    WHERE id = $session_id";
2509
            Database::query($sql);
2510
            return true;
2511
        } else {
2512
            return false;
2513
        }
2514
    }
2515
2516
    /**
2517
     * Creates a new extra field for a given session
2518
     * @param	string	$variable Field's internal variable name
2519
     * @param	int		$fieldType Field's type
2520
     * @param	string	$displayText Field's language var name
2521
     * @return int     new extra field id
2522
     */
2523 View Code Duplication
    public static function create_session_extra_field($variable, $fieldType, $displayText)
2524
    {
2525
        $extraField = new ExtraFieldModel('session');
2526
        $params = [
2527
            'variable' => $variable,
2528
            'field_type' => $fieldType,
2529
            'display_text' => $displayText,
2530
        ];
2531
2532
        return $extraField->save($params);
2533
    }
2534
2535
    /**
2536
     * Update an extra field value for a given session
2537
     * @param	integer	Course ID
2538
     * @param	string	Field variable name
2539
     * @param	string	Field value
2540
     * @return	boolean	true if field updated, false otherwise
2541
     */
2542 View Code Duplication
    public static function update_session_extra_field_value($sessionId, $variable, $value = '')
2543
    {
2544
        $extraFieldValue = new ExtraFieldValue('session');
2545
        $params = [
2546
            'item_id' => $sessionId,
2547
            'variable' => $variable,
2548
            'value' => $value,
2549
        ];
2550
        return $extraFieldValue->save($params);
2551
    }
2552
2553
    /**
2554
     * Checks the relationship between a session and a course.
2555
     * @param int $session_id
2556
     * @param int $courseId
2557
     * @return bool Returns TRUE if the session and the course are related, FALSE otherwise.
2558
     * */
2559 View Code Duplication
    public static function relation_session_course_exist($session_id, $courseId)
2560
    {
2561
        $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2562
        $return_value = false;
2563
        $sql = "SELECT c_id FROM $tbl_session_course
2564
                WHERE
2565
                  session_id = " . intval($session_id) . " AND
2566
                  c_id = " . intval($courseId);
2567
        $result = Database::query($sql);
2568
        $num = Database::num_rows($result);
2569
        if ($num > 0) {
2570
            $return_value = true;
2571
        }
2572
        return $return_value;
2573
    }
2574
2575
    /**
2576
     * Get the session information by name
2577
     * @param string $session_name
2578
     * @return mixed false if the session does not exist, array if the session exist
2579
     * */
2580
    public static function get_session_by_name($session_name)
2581
    {
2582
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2583
        $session_name = trim($session_name);
2584
        if (empty($session_name)) {
2585
            return false;
2586
        }
2587
2588
        $sql = 'SELECT *
2589
		        FROM ' . $tbl_session . '
2590
		        WHERE name = "' . Database::escape_string($session_name) . '"';
2591
        $result = Database::query($sql);
2592
        $num = Database::num_rows($result);
2593
        if ($num > 0) {
2594
            return Database::fetch_array($result);
2595
        } else {
2596
            return false;
2597
        }
2598
    }
2599
2600
    /**
2601
     * Create a session category
2602
     * @author Jhon Hinojosa <[email protected]>, from existing code
2603
     * @param	string 		name
2604
     * @param 	integer		year_start
2605
     * @param 	integer		month_start
2606
     * @param 	integer		day_start
2607
     * @param 	integer		year_end
2608
     * @param 	integer		month_end
2609
     * @param 	integer		day_end
2610
     * @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...
2611
     * */
2612
    public static function create_category_session(
2613
        $sname,
2614
        $syear_start,
2615
        $smonth_start,
2616
        $sday_start,
2617
        $syear_end,
2618
        $smonth_end,
2619
        $sday_end
2620
    ) {
2621
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2622
        $name = trim($sname);
2623
        $year_start = intval($syear_start);
2624
        $month_start = intval($smonth_start);
2625
        $day_start = intval($sday_start);
2626
        $year_end = intval($syear_end);
2627
        $month_end = intval($smonth_end);
2628
        $day_end = intval($sday_end);
2629
2630
        $date_start = "$year_start-" . (($month_start < 10) ? "0$month_start" : $month_start) . "-" . (($day_start < 10) ? "0$day_start" : $day_start);
2631
        $date_end = "$year_end-" . (($month_end < 10) ? "0$month_end" : $month_end) . "-" . (($day_end < 10) ? "0$day_end" : $day_end);
2632
2633 View Code Duplication
        if (empty($name)) {
2634
            $msg = get_lang('SessionCategoryNameIsRequired');
2635
            return $msg;
2636
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
2637
            $msg = get_lang('InvalidStartDate');
2638
            return $msg;
2639
        } elseif (!$month_end && !$day_end && !$year_end) {
2640
            $date_end = '';
2641
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
2642
            $msg = get_lang('InvalidEndDate');
2643
            return $msg;
2644
        } elseif ($date_start >= $date_end) {
2645
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
2646
            return $msg;
2647
        }
2648
2649
        $access_url_id = api_get_current_access_url_id();
2650
        $params = [
2651
            'name' => $name,
2652
            'date_start' => $date_start,
2653
            'access_url_id' => $access_url_id
2654
        ];
2655
2656
        if (!empty($date_end)) {
2657
            $params['date_end'] = $date_end;
2658
        }
2659
2660
        $id = Database::insert($tbl_session_category, $params);
2661
2662
        // Add event to system log
2663
        $user_id = api_get_user_id();
2664
        Event::addEvent(
2665
            LOG_SESSION_CATEGORY_CREATE,
2666
            LOG_SESSION_CATEGORY_ID,
2667
            $id,
0 ignored issues
show
Security Bug introduced by
It seems like $id defined by \Database::insert($tbl_session_category, $params) on line 2660 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...
2668
            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...
2669
            $user_id
2670
        );
2671
2672
        return $id;
2673
    }
2674
2675
    /**
2676
     * Edit a sessions category
2677
     * @author Jhon Hinojosa <[email protected]>,from existing code
2678
     * @param	integer		id
2679
     * @param	string 		name
2680
     * @param 	integer		year_start
2681
     * @param 	integer		month_start
2682
     * @param 	integer		day_start
2683
     * @param 	integer		year_end
2684
     * @param 	integer		month_end
2685
     * @param 	integer		day_end
2686
     * @return bool
2687
     * The parameter id is a primary key
2688
     * */
2689
    public static function edit_category_session(
2690
        $id,
2691
        $sname,
2692
        $syear_start,
2693
        $smonth_start,
2694
        $sday_start,
2695
        $syear_end,
2696
        $smonth_end,
2697
        $sday_end
2698
    ) {
2699
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2700
        $name = trim($sname);
2701
        $year_start = intval($syear_start);
2702
        $month_start = intval($smonth_start);
2703
        $day_start = intval($sday_start);
2704
        $year_end = intval($syear_end);
2705
        $month_end = intval($smonth_end);
2706
        $day_end = intval($sday_end);
2707
        $id = intval($id);
2708
        $date_start = "$year_start-" . (($month_start < 10) ? "0$month_start" : $month_start) . "-" . (($day_start < 10) ? "0$day_start" : $day_start);
2709
        $date_end = "$year_end-" . (($month_end < 10) ? "0$month_end" : $month_end) . "-" . (($day_end < 10) ? "0$day_end" : $day_end);
2710
2711 View Code Duplication
        if (empty($name)) {
2712
            $msg = get_lang('SessionCategoryNameIsRequired');
2713
            return $msg;
2714
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
2715
            $msg = get_lang('InvalidStartDate');
2716
            return $msg;
2717
        } elseif (!$month_end && !$day_end && !$year_end) {
2718
            $date_end = null;
2719
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
2720
            $msg = get_lang('InvalidEndDate');
2721
            return $msg;
2722
        } elseif ($date_start >= $date_end) {
2723
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
2724
            return $msg;
2725
        }
2726
        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...
2727
            $sql = "UPDATE $tbl_session_category
2728
                    SET
2729
                        name = '" . Database::escape_string($name) . "',
2730
                        date_start = '$date_start' ,
2731
                        date_end = '$date_end'
2732
                    WHERE id= $id";
2733
        } else {
2734
            $sql = "UPDATE $tbl_session_category SET
2735
                        name = '" . Database::escape_string($name) . "',
2736
                        date_start = '$date_start',
2737
                        date_end = NULL
2738
                    WHERE id= $id";
2739
        }
2740
        $result = Database::query($sql);
2741
        return ($result ? true : false);
2742
    }
2743
2744
    /**
2745
     * Delete sessions categories
2746
     * @author Jhon Hinojosa <[email protected]>, from existing code
2747
     * @param	array	id_checked
2748
     * @param	bool	include delete session
2749
     * @param	bool	optional, true if the function is called by a webservice, false otherwise.
2750
     * @return	void	Nothing, or false on error
2751
     * The parameters is a array to delete sessions
2752
     * */
2753
    public static function delete_session_category($id_checked, $delete_session = false, $from_ws = false)
2754
    {
2755
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2756
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2757
        if (is_array($id_checked)) {
2758
            $id_checked = Database::escape_string(implode(',', $id_checked));
2759
        } else {
2760
            $id_checked = intval($id_checked);
2761
        }
2762
2763
        //Setting session_category_id to 0
2764
        $sql = "UPDATE $tbl_session SET session_category_id = NULL
2765
                WHERE session_category_id IN (" . $id_checked . ")";
2766
        Database::query($sql);
2767
2768
        $sql = "SELECT id FROM $tbl_session WHERE session_category_id IN (" . $id_checked . ")";
2769
        $result = Database::query($sql);
2770
        while ($rows = Database::fetch_array($result)) {
2771
            $session_id = $rows['id'];
2772
            if ($delete_session) {
2773
                if ($from_ws) {
2774
                    self::delete($session_id, true);
2775
                } else {
2776
                    self::delete($session_id);
2777
                }
2778
            }
2779
        }
2780
        $sql = "DELETE FROM $tbl_session_category WHERE id IN (" . $id_checked . ")";
2781
        Database::query($sql);
2782
2783
        // Add event to system log
2784
        $user_id = api_get_user_id();
2785
        Event::addEvent(
2786
            LOG_SESSION_CATEGORY_DELETE,
2787
            LOG_SESSION_CATEGORY_ID,
2788
            $id_checked,
2789
            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...
2790
            $user_id
2791
        );
2792
2793
        return true;
2794
    }
2795
2796
    /**
2797
     * Get a list of sessions of which the given conditions match with an = 'cond'
2798
     * @param  array $conditions a list of condition example :
2799
     * array('status' => STUDENT) or
2800
     * array('s.name' => array('operator' => 'LIKE', value = '%$needle%'))
2801
     * @param  array $order_by a list of fields on which sort
2802
     * @return array An array with all sessions of the platform.
2803
     * @todo   optional course code parameter, optional sorting parameters...
2804
     */
2805
    public static function get_sessions_list($conditions = array(), $order_by = array(), $from = null, $to = null)
2806
    {
2807
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
2808
        $session_category_table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2809
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
2810
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
2811
        $session_course_table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2812
        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
2813
        $access_url_id = api_get_current_access_url_id();
2814
        $return_array = array();
2815
2816
        $sql_query = " SELECT
2817
                    DISTINCT(s.id),
2818
                    s.name,
2819
                    s.nbr_courses,
2820
                    s.access_start_date,
2821
                    s.access_end_date,
2822
                    u.firstname,
2823
                    u.lastname,
2824
                    sc.name as category_name,
2825
                    s.promotion_id
2826
				FROM $session_table s
2827
				INNER JOIN $user_table u ON s.id_coach = u.user_id
2828
				INNER JOIN $table_access_url_rel_session ar ON ar.session_id = s.id
2829
				LEFT JOIN  $session_category_table sc ON s.session_category_id = sc.id
2830
				LEFT JOIN $session_course_table sco ON (sco.session_id = s.id)
2831
				INNER JOIN $course_table c ON sco.c_id = c.id
2832
				WHERE ar.access_url_id = $access_url_id ";
2833
2834
        $availableFields = array(
2835
            's.id',
2836
            's.name',
2837
            'c.id'
2838
        );
2839
2840
        $availableOperator = array(
2841
            'like',
2842
            '>=',
2843
            '<=',
2844
            '=',
2845
        );
2846
2847
        if (count($conditions) > 0) {
2848
            foreach ($conditions as $field => $options) {
2849
                $operator = strtolower($options['operator']);
2850
                $value = Database::escape_string($options['value']);
2851
                $sql_query .= ' AND ';
2852
                if (in_array($field, $availableFields) && in_array($operator, $availableOperator)) {
2853
                    $sql_query .= $field . " $operator '" . $value . "'";
2854
                }
2855
            }
2856
        }
2857
2858
        $orderAvailableList = array('name');
2859
2860
        if (count($order_by) > 0) {
2861
            $order = null;
2862
            $direction = null;
2863
            if (isset($order_by[0]) && in_array($order_by[0], $orderAvailableList)) {
2864
                $order = $order_by[0];
2865
            }
2866
            if (isset($order_by[1]) && in_array(strtolower($order_by[1]), array('desc', 'asc'))) {
2867
                $direction = $order_by[1];
2868
            }
2869
2870
            if (!empty($order)) {
2871
                $sql_query .= " ORDER BY $order $direction ";
2872
            }
2873
        }
2874
2875
        if (!is_null($from) && !is_null($to)) {
2876
            $to = intval($to);
2877
            $from = intval($from);
2878
            $sql_query .= "LIMIT $from, $to";
2879
        }
2880
2881
        $sql_result = Database::query($sql_query);
2882
        if (Database::num_rows($sql_result) > 0) {
2883
            while ($result = Database::fetch_array($sql_result)) {
2884
                $return_array[$result['id']] = $result;
2885
            }
2886
        }
2887
2888
        return $return_array;
2889
    }
2890
2891
    /**
2892
     * Get the session category information by id
2893
     * @param string session category ID
2894
     * @return mixed false if the session category does not exist, array if the session category exists
2895
     */
2896 View Code Duplication
    public static function get_session_category($id)
2897
    {
2898
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2899
        $id = intval($id);
2900
        $sql = "SELECT id, name, date_start, date_end
2901
                FROM $tbl_session_category
2902
                WHERE id= $id";
2903
        $result = Database::query($sql);
2904
        $num = Database::num_rows($result);
2905
        if ($num > 0) {
2906
            return Database::fetch_array($result);
2907
        } else {
2908
            return false;
2909
        }
2910
    }
2911
2912
    /**
2913
     * Get all session categories (filter by access_url_id)
2914
     * @return mixed false if the session category does not exist, array if the session category exists
2915
     */
2916
    public static function get_all_session_category()
2917
    {
2918
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2919
        $id = api_get_current_access_url_id();
2920
        $sql = 'SELECT * FROM ' . $tbl_session_category . '
2921
                WHERE access_url_id = ' . $id . '
2922
                ORDER BY name ASC';
2923
        $result = Database::query($sql);
2924
        if (Database::num_rows($result) > 0) {
2925
            $data = Database::store_result($result, 'ASSOC');
2926
            return $data;
2927
        } else {
2928
            return false;
2929
        }
2930
    }
2931
2932
    /**
2933
     * Assign a coach to course in session with status = 2
2934
     * @param int  $user_id
2935
     * @param int  $session_id
2936
     * @param int  $courseId
2937
     * @param bool $nocoach optional, if is true the user don't be a coach now,
2938
     * otherwise it'll assign a coach
2939
     * @return bool true if there are affected rows, otherwise false
2940
     */
2941
    public static function set_coach_to_course_session(
2942
        $user_id,
2943
        $session_id = 0,
2944
        $courseId = 0,
2945
        $nocoach = false
2946
    ) {
2947
        // Definition of variables
2948
        $user_id = intval($user_id);
2949
2950
        if (!empty($session_id)) {
2951
            $session_id = intval($session_id);
2952
        } else {
2953
            $session_id = api_get_session_id();
2954
        }
2955
2956
        if (!empty($courseId)) {
2957
            $courseId = intval($courseId);
2958
        } else {
2959
            $courseId = api_get_course_id();
2960
        }
2961
2962
        if (empty($session_id) || empty($courseId) || empty($user_id)) {
2963
            return false;
2964
        }
2965
2966
        // Table definition
2967
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2968
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2969
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
2970
2971
        // check if user is a teacher
2972
        $sql = "SELECT * FROM $tbl_user
2973
                WHERE status = 1 AND user_id = $user_id";
2974
2975
        $rs_check_user = Database::query($sql);
2976
2977
        if (Database::num_rows($rs_check_user) > 0) {
2978
            if ($nocoach) {
2979
                // check if user_id exists in session_rel_user (if the user is
2980
                // subscribed to the session in any manner)
2981
                $sql = "SELECT user_id FROM $tbl_session_rel_user
2982
                        WHERE
2983
                            session_id = $session_id AND
2984
                            user_id = $user_id";
2985
                $res = Database::query($sql);
2986
2987 View Code Duplication
                if (Database::num_rows($res) > 0) {
2988
                    // The user is already subscribed to the session. Change the
2989
                    // record so the user is NOT a coach for this course anymore
2990
                    // and then exit
2991
                    $sql = "UPDATE $tbl_session_rel_course_rel_user
2992
                            SET status = 0
2993
                            WHERE
2994
                                session_id = $session_id AND
2995
                                c_id = $courseId AND
2996
                                user_id = $user_id ";
2997
                    $result = Database::query($sql);
2998
                    if (Database::affected_rows($result) > 0)
2999
                        return true;
3000
                    else
3001
                        return false;
3002
                } else {
3003
                    // The user is not subscribed to the session, so make sure
3004
                    // he isn't subscribed to a course in this session either
3005
                    // and then exit
3006
                    $sql = "DELETE FROM $tbl_session_rel_course_rel_user
3007
                            WHERE
3008
                                session_id = $session_id AND
3009
                                c_id = $courseId AND
3010
                                user_id = $user_id ";
3011
                    $result = Database::query($sql);
3012
                    if (Database::affected_rows($result) > 0) {
3013
                        return true;
3014
                    } else {
3015
                        return false;
3016
                    }
3017
                }
3018
            } else {
3019
                // Assign user as a coach to course
3020
                // First check if the user is registered to the course
3021
                $sql = "SELECT user_id FROM $tbl_session_rel_course_rel_user
3022
                        WHERE
3023
                            session_id = $session_id AND
3024
                            c_id = $courseId AND
3025
                            user_id = $user_id";
3026
                $rs_check = Database::query($sql);
3027
3028
                // Then update or insert.
3029 View Code Duplication
                if (Database::num_rows($rs_check) > 0) {
3030
                    $sql = "UPDATE $tbl_session_rel_course_rel_user SET status = 2
3031
					        WHERE
3032
					            session_id = $session_id AND
3033
					            c_id = $courseId AND
3034
					            user_id = $user_id ";
3035
                    $result = Database::query($sql);
3036
                    if (Database::affected_rows($result) > 0) {
3037
                        return true;
3038
                    } else {
3039
                        return false;
3040
                    }
3041
                } else {
3042
                    $sql = "INSERT INTO $tbl_session_rel_course_rel_user(session_id, c_id, user_id, status, visibility)
3043
                            VALUES($session_id, $courseId, $user_id, 2, 1)";
3044
                    $result = Database::query($sql);
3045
                    if (Database::affected_rows($result) > 0) {
3046
                        return true;
3047
                    } else {
3048
                        return false;
3049
                    }
3050
                }
3051
            }
3052
        } else {
3053
            return false;
3054
        }
3055
    }
3056
3057
    /**
3058
     * @param int $sessionId
3059
     * @return bool
3060
     */
3061 View Code Duplication
    public static function removeAllDrhFromSession($sessionId)
3062
    {
3063
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3064
3065
        $sessionId = (int) $sessionId;
3066
3067
        if (empty($sessionId)) {
3068
            return false;
3069
        }
3070
3071
        $sql = "DELETE FROM $tbl_session_rel_user
3072
                WHERE
3073
                    session_id = $sessionId AND                            
3074
                    relation_type =" . SESSION_RELATION_TYPE_RRHH;
3075
        Database::query($sql);
3076
3077
        return true;
3078
    }
3079
3080
    /**
3081
     * Subscribes sessions to human resource manager (Dashboard feature)
3082
     * @param array $userInfo Human Resource Manager info
3083
     * @param array $sessions_list Sessions id
3084
     * @param bool $sendEmail
3085
     * @param bool $removeSessionsFromUser
3086
     * @return int
3087
     * */
3088
    public static function subscribeSessionsToDrh(
3089
        $userInfo,
3090
        $sessions_list,
3091
        $sendEmail = false,
3092
        $removeSessionsFromUser = true
3093
    ) {
3094
        // Database Table Definitions
3095
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3096
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3097
3098
        if (empty($userInfo)) {
3099
3100
            return 0;
3101
        }
3102
3103
        $userId = $userInfo['user_id'];
3104
3105
        // Only subscribe DRH users.
3106
        $rolesAllowed = array(
3107
            DRH,
3108
            SESSIONADMIN,
3109
            PLATFORM_ADMIN,
3110
            COURSE_TUTOR
3111
        );
3112
        $isAdmin = api_is_platform_admin_by_id($userInfo['user_id']);
3113
        if (!$isAdmin && !in_array($userInfo['status'], $rolesAllowed)) {
3114
3115
            return 0;
3116
        }
3117
3118
        $affected_rows = 0;
3119
        // Deleting assigned sessions to hrm_id.
3120
        if ($removeSessionsFromUser) {
3121
            if (api_is_multiple_url_enabled()) {
3122
                $sql = "SELECT s.session_id
3123
                        FROM $tbl_session_rel_user s
3124
                        INNER JOIN $tbl_session_rel_access_url a 
3125
                        ON (a.session_id = s.session_id)
3126
                        WHERE
3127
                            s.user_id = $userId AND
3128
                            relation_type = " . SESSION_RELATION_TYPE_RRHH . " AND
3129
                            access_url_id = " . api_get_current_access_url_id();
3130
            } else {
3131
                $sql = "SELECT s.session_id 
3132
                        FROM $tbl_session_rel_user s
3133
                        WHERE user_id = $userId AND relation_type=" . SESSION_RELATION_TYPE_RRHH;
3134
            }
3135
            $result = Database::query($sql);
3136
3137 View Code Duplication
            if (Database::num_rows($result) > 0) {
3138
                while ($row = Database::fetch_array($result)) {
3139
                    $sql = "DELETE FROM $tbl_session_rel_user
3140
                            WHERE
3141
                                session_id = {$row['session_id']} AND
3142
                                user_id = $userId AND
3143
                                relation_type =" . SESSION_RELATION_TYPE_RRHH;
3144
                    Database::query($sql);
3145
                }
3146
            }
3147
        }
3148
3149
        // Inserting new sessions list.
3150
        if (!empty($sessions_list) && is_array($sessions_list)) {
3151
            foreach ($sessions_list as $session_id) {
3152
                $session_id = intval($session_id);
3153
                $sql = "SELECT session_id
3154
                        FROM $tbl_session_rel_user
3155
                        WHERE
3156
                            session_id = $session_id AND
3157
                            user_id = $userId AND
3158
                            relation_type = '" . SESSION_RELATION_TYPE_RRHH . "'";
3159
                $result = Database::query($sql);
3160
                if (Database::num_rows($result) == 0) {
3161
                    $sql = "INSERT IGNORE INTO $tbl_session_rel_user (session_id, user_id, relation_type, registered_at)
3162
                            VALUES (
3163
                                $session_id,
3164
                                $userId,
3165
                                '".SESSION_RELATION_TYPE_RRHH."',
3166
                                '".api_get_utc_datetime()."'
3167
                            )";
3168
                    Database::query($sql);
3169
                    $affected_rows++;
3170
                }
3171
            }
3172
        }
3173
3174
        return $affected_rows;
3175
    }
3176
3177
    /**
3178
     * @param int $sessionId
3179
     * @return array
3180
     */
3181
    public static function getDrhUsersInSession($sessionId)
3182
    {
3183
        return self::get_users_by_session($sessionId, SESSION_RELATION_TYPE_RRHH);
3184
    }
3185
3186
    /**
3187
     * @param int $userId
3188
     * @param int $sessionId
3189
     * @return array
3190
     */
3191
    public static function getSessionFollowedByDrh($userId, $sessionId)
3192
    {
3193
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3194
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3195
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3196
3197
        $userId = intval($userId);
3198
        $sessionId = intval($sessionId);
3199
3200
        $select = " SELECT * ";
3201
        if (api_is_multiple_url_enabled()) {
3202
            $sql = " $select FROM $tbl_session s
3203
                    INNER JOIN $tbl_session_rel_user sru ON (sru.session_id = s.id)
3204
                    LEFT JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
3205
                    WHERE
3206
                        sru.user_id = '$userId' AND
3207
                        sru.session_id = '$sessionId' AND
3208
                        sru.relation_type = '" . SESSION_RELATION_TYPE_RRHH . "' AND
3209
                        access_url_id = " . api_get_current_access_url_id() . "
3210
                        ";
3211
        } else {
3212
            $sql = "$select FROM $tbl_session s
3213
                     INNER JOIN $tbl_session_rel_user sru
3214
                     ON
3215
                        sru.session_id = s.id AND
3216
                        sru.user_id = '$userId' AND
3217
                        sru.session_id = '$sessionId' AND
3218
                        sru.relation_type = '" . SESSION_RELATION_TYPE_RRHH . "'
3219
                    ";
3220
        }
3221
3222
        $result = Database::query($sql);
3223
        if (Database::num_rows($result)) {
3224
            $row = Database::fetch_array($result, 'ASSOC');
3225
            $row['course_list'] = self::get_course_list_by_session_id($sessionId);
3226
3227
            return $row;
3228
        }
3229
3230
        return array();
3231
    }
3232
3233
    /**
3234
     * Get sessions followed by human resources manager
3235
     * @param int $userId
3236
     * @param int $start
3237
     * @param int $limit
3238
     * @param bool $getCount
3239
     * @param bool $getOnlySessionId
3240
     * @param bool $getSql
3241
     * @param string $orderCondition
3242
     * @param string $keyword
3243
     * @param string $description
3244
     *
3245
     * @return array sessions
3246
     */
3247
    public static function get_sessions_followed_by_drh(
3248
        $userId,
3249
        $start = null,
3250
        $limit = null,
3251
        $getCount = false,
3252
        $getOnlySessionId = false,
3253
        $getSql = false,
3254
        $orderCondition = null,
3255
        $keyword = '',
3256
        $description = ''
3257
    ) {
3258
        return self::getSessionsFollowedByUser(
3259
            $userId,
3260
            DRH,
3261
            $start,
3262
            $limit,
3263
            $getCount,
3264
            $getOnlySessionId,
3265
            $getSql,
3266
            $orderCondition,
3267
            $keyword,
3268
            $description
3269
        );
3270
    }
3271
3272
    /**
3273
     * Get sessions followed by human resources manager
3274
     * @param int $userId
3275
     * @param int $status Optional
3276
     * @param int $start
3277
     * @param int $limit
3278
     * @param bool $getCount
3279
     * @param bool $getOnlySessionId
3280
     * @param bool $getSql
3281
     * @param string $orderCondition
3282
     * @param string $keyword
3283
     * @param string $description
3284
     * @return array sessions
3285
     */
3286
    public static function getSessionsFollowedByUser(
3287
        $userId,
3288
        $status = null,
3289
        $start = null,
3290
        $limit = null,
3291
        $getCount = false,
3292
        $getOnlySessionId = false,
3293
        $getSql = false,
3294
        $orderCondition = null,
3295
        $keyword = '',
3296
        $description = ''
3297
    ) {
3298
        // Database Table Definitions
3299
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3300
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3301
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3302
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3303
3304
        $userId = intval($userId);
3305
3306
        $select = " SELECT DISTINCT * ";
3307
3308
        if ($getCount) {
3309
            $select = " SELECT count(DISTINCT(s.id)) as count ";
3310
        }
3311
3312
        if ($getOnlySessionId) {
3313
            $select = " SELECT DISTINCT(s.id) ";
3314
        }
3315
3316
        $limitCondition = null;
3317 View Code Duplication
        if (!empty($start) && !empty($limit)) {
3318
            $limitCondition = " LIMIT " . intval($start) . ", " . intval($limit);
3319
        }
3320
3321
        if (empty($orderCondition)) {
3322
            $orderCondition = " ORDER BY s.name ";
3323
        }
3324
3325
        $whereConditions = null;
3326
        $sessionCourseConditions = null;
3327
        $sessionConditions = null;
3328
        $sessionQuery = null;
3329
        $courseSessionQuery = null;
3330
3331
        switch ($status) {
3332
            case DRH:
3333
                $sessionQuery = "SELECT sru.session_id
3334
                                 FROM
3335
                                 $tbl_session_rel_user sru
3336
                                 WHERE
3337
                                    sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."' AND
3338
                                    sru.user_id = $userId";
3339
                break;
3340
            case COURSEMANAGER:
3341
                $courseSessionQuery = "
3342
                    SELECT scu.session_id as id
3343
                    FROM $tbl_session_rel_course_rel_user scu
3344
                    WHERE (scu.status = 2 AND scu.user_id = $userId)";
3345
3346
                $whereConditions = " OR (s.id_coach = $userId) ";
3347
                break;
3348
            default:
3349
                $sessionQuery = "SELECT sru.session_id
3350
                                 FROM
3351
                                 $tbl_session_rel_user sru
3352
                                 WHERE
3353
                                    sru.user_id = $userId";
3354
                break;
3355
        }
3356
3357
        $keywordCondition = '';
3358 View Code Duplication
        if (!empty($keyword)) {
3359
            $keyword = Database::escape_string($keyword);
3360
            $keywordCondition = " AND (s.name LIKE '%$keyword%' ) ";
3361
3362
            if (!empty($description)) {
3363
                $description = Database::escape_string($description);
3364
                $keywordCondition = " AND (s.name LIKE '%$keyword%' OR s.description LIKE '%$description%' ) ";
3365
            }
3366
        }
3367
3368
        $whereConditions .= $keywordCondition;
3369
        $subQuery = $sessionQuery.$courseSessionQuery;
3370
3371
        $sql = " $select FROM $tbl_session s
3372
                INNER JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
3373
                WHERE
3374
                    access_url_id = ".api_get_current_access_url_id()." AND
3375
                    s.id IN (
3376
                        $subQuery
3377
                    )
3378
                    $whereConditions
3379
                    $orderCondition
3380
                    $limitCondition";
3381
3382
        if ($getSql) {
3383
            return $sql;
3384
        }
3385
3386
        $result = Database::query($sql);
3387
3388
        if ($getCount) {
3389
            $row = Database::fetch_array($result);
3390
            return $row['count'];
3391
        }
3392
3393
        $sessions = array();
3394
        if (Database::num_rows($result) > 0) {
3395
            $sysUploadPath = api_get_path(SYS_UPLOAD_PATH). 'sessions/';
3396
            $webUploadPath = api_get_path(WEB_UPLOAD_PATH). 'sessions/';
3397
            $imgPath = Display::return_icon('session_default_small.png', null, null, null, null, true);
3398
3399
            $tableExtraFields = Database::get_main_table(TABLE_EXTRA_FIELD);
3400
            $sql = "SELECT id FROM " . $tableExtraFields . "
3401
                    WHERE extra_field_type = 3 AND variable='image'";
3402
            $resultField = Database::query($sql);
3403
            $imageFieldId = Database::fetch_assoc($resultField);
3404
3405
            while ($row = Database::fetch_array($result)) {
3406
3407
                $row['image'] =  null;
3408
                $sessionImage = $sysUploadPath . $imageFieldId['id'] . '_' . $row['id'] . '.png';
3409
3410
                if (is_file($sessionImage)) {
3411
                    $sessionImage = $webUploadPath . $imageFieldId['id'] . '_' . $row['id'] . '.png';
3412
                    $row['image'] = $sessionImage;
3413
                } else {
3414
                    $row['image'] =  $imgPath;
3415
                }
3416
3417
                if ($row['display_start_date'] == '0000-00-00 00:00:00' || $row['display_start_date'] == '0000-00-00') {
3418
                    $row['display_start_date'] = null;
3419
                }
3420
3421
                if ($row['display_end_date'] == '0000-00-00 00:00:00' || $row['display_end_date'] == '0000-00-00') {
3422
                    $row['display_end_date'] = null;
3423
                }
3424
3425
                if ($row['access_start_date'] == '0000-00-00 00:00:00' || $row['access_start_date'] == '0000-00-00') {
3426
                    $row['access_start_date'] = null;
3427
                }
3428
3429
                if ($row['access_end_date'] == '0000-00-00 00:00:00' || $row['access_end_date'] == '0000-00-00') {
3430
                    $row['access_end_date'] = null;
3431
                }
3432
3433
                if (
3434
                    $row['coach_access_start_date'] == '0000-00-00 00:00:00' ||
3435
                    $row['coach_access_start_date'] == '0000-00-00'
3436
                ) {
3437
                    $row['coach_access_start_date'] = null;
3438
                }
3439
3440
                if (
3441
                    $row['coach_access_end_date'] == '0000-00-00 00:00:00' ||
3442
                    $row['coach_access_end_date'] == '0000-00-00'
3443
                ) {
3444
                    $row['coach_access_end_date'] = null;
3445
                }
3446
3447
                $sessions[$row['id']] = $row;
3448
3449
            }
3450
        }
3451
3452
        return $sessions;
3453
    }
3454
3455
    /**
3456
     * Gets the list (or the count) of courses by session filtered by access_url
3457
     * @param int $session_id The session id
3458
     * @param string $course_name The course code
3459
     * @param string $orderBy Field to order the data
3460
     * @param boolean $getCount Optional. Count the session courses
3461
     * @return array|int List of courses. Whether $getCount is true, return the count
3462
     */
3463
    public static function get_course_list_by_session_id(
3464
        $session_id,
3465
        $course_name = '',
3466
        $orderBy = null,
3467
        $getCount = false
3468
    ) {
3469
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3470
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3471
3472
        $session_id = intval($session_id);
3473
3474
        $sqlSelect = "*, c.id, c.id as real_id";
3475
3476
        if ($getCount) {
3477
            $sqlSelect = "COUNT(1) as count";
3478
        }
3479
3480
        // select the courses
3481
        $sql = "SELECT $sqlSelect
3482
                FROM $tbl_course c
3483
                INNER JOIN $tbl_session_rel_course src
3484
                ON (c.id = src.c_id)
3485
		        WHERE src.session_id = '$session_id' ";
3486
3487
        if (!empty($course_name)) {
3488
            $course_name = Database::escape_string($course_name);
3489
            $sql .= " AND c.title LIKE '%$course_name%' ";
3490
        }
3491
3492
        if (!empty($orderBy)) {
3493
            $orderBy = Database::escape_string($orderBy);
3494
            $orderBy = " ORDER BY $orderBy";
3495
        } else {
3496
            if (self::orderCourseIsEnabled()) {
3497
                $orderBy .= " ORDER BY position ";
3498
            } else {
3499
                $orderBy .= " ORDER BY title ";
3500
            }
3501
        }
3502
3503
        $sql .= Database::escape_string($orderBy);
3504
        $result = Database::query($sql);
3505
        $num_rows = Database::num_rows($result);
3506
        $courses = array();
3507 View Code Duplication
        if ($num_rows > 0) {
3508
            if ($getCount) {
3509
                $count = Database::fetch_assoc($result);
3510
3511
                return intval($count['count']);
3512
            }
3513
3514
            while ($row = Database::fetch_array($result,'ASSOC'))	{
3515
                $courses[$row['real_id']] = $row;
3516
            }
3517
        }
3518
3519
        return $courses;
3520
    }
3521
3522
    /**
3523
     * Gets the list of courses by session filtered by access_url
3524
     *
3525
     * @param $userId
3526
     * @param $sessionId
3527
     * @param null $from
3528
     * @param null $limit
3529
     * @param null $column
3530
     * @param null $direction
3531
     * @param bool $getCount
3532
     * @return array
3533
     */
3534
    public static function getAllCoursesFollowedByUser(
3535
        $userId,
3536
        $sessionId,
3537
        $from = null,
3538
        $limit = null,
3539
        $column = null,
3540
        $direction = null,
3541
        $getCount = false,
3542
        $keyword = null
3543
    ) {
3544
        if (empty($sessionId)) {
3545
            $sessionsSQL = self::get_sessions_followed_by_drh(
3546
                $userId,
3547
                null,
3548
                null,
3549
                null,
3550
                true,
3551
                true
3552
            );
3553
        } else {
3554
            $sessionsSQL = intval($sessionId);
3555
        }
3556
3557
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3558
        $tbl_session_rel_course	= Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3559
3560
        if ($getCount) {
3561
            $select = "SELECT COUNT(DISTINCT(c.code)) as count ";
3562
        } else {
3563
            $select = "SELECT DISTINCT c.* ";
3564
        }
3565
3566
        $keywordCondition = null;
3567
        if (!empty($keyword)) {
3568
            $keyword = Database::escape_string($keyword);
3569
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
3570
        }
3571
3572
        // Select the courses
3573
        $sql = "$select
3574
                FROM $tbl_course c
3575
                INNER JOIN $tbl_session_rel_course src
3576
                ON c.id = src.c_id
3577
		        WHERE
3578
		            src.session_id IN ($sessionsSQL)
3579
		            $keywordCondition
3580
		        ";
3581 View Code Duplication
        if ($getCount) {
3582
            $result = Database::query($sql);
3583
            $row = Database::fetch_array($result,'ASSOC');
3584
            return $row['count'];
3585
        }
3586
3587 View Code Duplication
        if (isset($from) && isset($limit)) {
3588
            $from = intval($from);
3589
            $limit = intval($limit);
3590
            $sql .= " LIMIT $from, $limit";
3591
        }
3592
3593
        $result = Database::query($sql);
3594
        $num_rows = Database::num_rows($result);
3595
        $courses = array();
3596
3597
        if ($num_rows > 0) {
3598
            while ($row = Database::fetch_array($result,'ASSOC'))	{
3599
                $courses[$row['id']] = $row;
3600
            }
3601
        }
3602
3603
        return $courses;
3604
    }
3605
3606
    /**
3607
     * Gets the list of courses by session filtered by access_url
3608
     * @param int $session_id
3609
     * @param string $course_name
3610
     * @return array list of courses
3611
     */
3612
    public static function get_course_list_by_session_id_like($session_id, $course_name = '')
3613
    {
3614
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3615
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3616
3617
        $session_id = intval($session_id);
3618
        $course_name = Database::escape_string($course_name);
3619
3620
        // select the courses
3621
        $sql = "SELECT c.id, c.title FROM $tbl_course c
3622
                INNER JOIN $tbl_session_rel_course src
3623
                ON c.id = src.c_id
3624
		        WHERE ";
3625
3626
        if (!empty($session_id)) {
3627
            $sql .= "src.session_id LIKE '$session_id' AND ";
3628
        }
3629
3630
        if (!empty($course_name)) {
3631
            $sql .= "UPPER(c.title) LIKE UPPER('%$course_name%') ";
3632
        }
3633
3634
        $sql .= "ORDER BY title;";
3635
        $result = Database::query($sql);
3636
        $num_rows = Database::num_rows($result);
3637
        $courses = array();
3638
        if ($num_rows > 0) {
3639
            while ($row = Database::fetch_array($result, 'ASSOC')) {
3640
                $courses[$row['id']] = $row;
3641
            }
3642
        }
3643
3644
        return $courses;
3645
    }
3646
3647
3648
    /**
3649
     * Gets the count of courses by session filtered by access_url
3650
     * @param int session id
3651
     * @return array list of courses
3652
     */
3653
    public static function getCourseCountBySessionId($session_id, $keyword = null)
3654
    {
3655
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3656
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3657
        $session_id = intval($session_id);
3658
3659
        // select the courses
3660
        $sql = "SELECT COUNT(c.code) count
3661
                FROM $tbl_course c
3662
                INNER JOIN $tbl_session_rel_course src
3663
                ON c.id = src.c_id
3664
		        WHERE src.session_id = '$session_id' ";
3665
3666
        $keywordCondition = null;
3667
        if (!empty($keyword)) {
3668
            $keyword = Database::escape_string($keyword);
3669
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
3670
        }
3671
        $sql .= $keywordCondition;
3672
3673
        $result = Database::query($sql);
3674
        $num_rows = Database::num_rows($result);
3675
        if ($num_rows > 0) {
3676
            $row = Database::fetch_array($result,'ASSOC');
3677
            return $row['count'];
3678
        }
3679
3680
        return null;
3681
    }
3682
3683
    /**
3684
     * Get the session id based on the original id and field name in the extra fields.
3685
     * Returns 0 if session was not found
3686
     *
3687
     * @param string $value Original session id
3688
     * @param string $variable Original field name
3689
     * @return int Session id
3690
     */
3691
    public static function getSessionIdFromOriginalId($value, $variable)
3692
    {
3693
        $extraFieldValue = new ExtraFieldValue('session');
3694
        $result = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
3695
            $variable,
3696
            $value
3697
        );
3698
3699
        if (!empty($result)) {
3700
            return $result['item_id'];
3701
        }
3702
3703
        return 0;
3704
    }
3705
3706
    /**
3707
     * Get users by session
3708
     * @param  int $id session id
3709
     * @param    int $status filter by status coach = 2
3710
     * @param bool $getCount Optional. Allow get the number of rows from the result
3711
     * @return array|int A list with an user list. If $getCount is true then return a the count of registers
3712
     */
3713
    public static function get_users_by_session($id, $status = null, $getCount = false)
3714
    {
3715
        if (empty($id)) {
3716
            return array();
3717
        }
3718
        $id = intval($id);
3719
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
3720
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3721
        $table_access_url_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
3722
3723
        $selectedField = 'u.user_id,lastname, firstname, username, relation_type, access_url_id';
3724
3725
        if ($getCount) {
3726
            $selectedField = 'count(1) AS count';
3727
        }
3728
3729
        $sql = "SELECT $selectedField
3730
                FROM $tbl_user u
3731
                INNER JOIN $tbl_session_rel_user
3732
                ON u.user_id = $tbl_session_rel_user.user_id AND
3733
                $tbl_session_rel_user.session_id = $id
3734
                LEFT OUTER JOIN $table_access_url_user uu
3735
                ON (uu.user_id = u.user_id)
3736
                ";
3737
3738
        $urlId = api_get_current_access_url_id();
3739
        if (isset($status) && $status != '') {
3740
            $status = intval($status);
3741
            $sql .= " WHERE relation_type = $status AND (access_url_id = $urlId OR access_url_id is null )";
3742
        } else {
3743
            $sql .= " WHERE (access_url_id = $urlId OR access_url_id is null )";
3744
        }
3745
3746
        $sql .= " ORDER BY relation_type, ";
3747
        $sql .= api_sort_by_first_name() ? ' firstname, lastname' : '  lastname, firstname';
3748
3749
        $result = Database::query($sql);
3750
3751
        if ($getCount) {
3752
            $count = Database::fetch_assoc($result);
3753
3754
            return $count['count'];
3755
        }
3756
3757
        $return = array();
3758
        while ($row = Database::fetch_array($result, 'ASSOC')) {
3759
            $return[] = $row;
3760
        }
3761
3762
        return $return;
3763
    }
3764
3765
    /**
3766
     * The general coach (field: session.id_coach)
3767
     * @param int $user_id user id
3768
     * @param boolean   $asPlatformAdmin The user is platform admin, return everything
3769
     * @return array
3770
     */
3771
    public static function get_sessions_by_general_coach($user_id, $asPlatformAdmin = false)
3772
    {
3773
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
3774
        $user_id = intval($user_id);
3775
3776
        // Session where we are general coach
3777
        $sql = "SELECT DISTINCT *
3778
                FROM $session_table";
3779
3780
        if (!$asPlatformAdmin) {
3781
            $sql .= " WHERE id_coach = $user_id";
3782
        }
3783
3784
        if (api_is_multiple_url_enabled()) {
3785
            $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3786
            $access_url_id = api_get_current_access_url_id();
3787
3788
            $sqlCoach = '';
3789
            if (!$asPlatformAdmin) {
3790
                $sqlCoach = " id_coach = $user_id AND ";
3791
            }
3792
3793
            if ($access_url_id != -1) {
3794
                $sql = 'SELECT DISTINCT session.*
3795
                    FROM ' . $session_table . ' session INNER JOIN ' . $tbl_session_rel_access_url . ' session_rel_url
3796
                    ON (session.id = session_rel_url.session_id)
3797
                    WHERE '.$sqlCoach.' access_url_id = ' . $access_url_id;
3798
            }
3799
        }
3800
        $sql .= ' ORDER by name';
3801
        $result = Database::query($sql);
3802
3803
        return Database::store_result($result, 'ASSOC');
3804
    }
3805
3806
    /**
3807
     * @param int $user_id
3808
     * @return array
3809
     * @deprecated use get_sessions_by_general_coach()
3810
     */
3811
    public static function get_sessions_by_coach($user_id)
3812
    {
3813
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
3814
        return Database::select('*', $session_table, array('where' => array('id_coach = ?' => $user_id)));
3815
    }
3816
3817
    /**
3818
     * @param int $user_id
3819
     * @param int $courseId
3820
     * @param int $session_id
3821
     * @return array|bool
3822
     */
3823 View Code Duplication
    public static function get_user_status_in_course_session($user_id, $courseId, $session_id)
3824
    {
3825
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3826
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
3827
        $sql = "SELECT session_rcru.status
3828
                FROM $tbl_session_rel_course_rel_user session_rcru, $tbl_user user
3829
                WHERE
3830
                    session_rcru.user_id = user.user_id AND
3831
                    session_rcru.session_id = '" . intval($session_id) . "' AND
3832
                    session_rcru.c_id ='" . intval($courseId) . "' AND
3833
                    user.user_id = " . intval($user_id);
3834
3835
        $result = Database::query($sql);
3836
        $status = false;
3837
        if (Database::num_rows($result)) {
3838
            $status = Database::fetch_row($result);
3839
            $status = $status['0'];
3840
        }
3841
3842
        return $status;
3843
    }
3844
3845
    /**
3846
     * Gets user status within a session
3847
     * @param int $user_id
3848
     * @param int $courseId
3849
     * @param $session_id
3850
     * @return int
3851
     * @assert (null,null,null) === false
3852
     */
3853
    public static function get_user_status_in_session($user_id, $courseId, $session_id)
3854
    {
3855
        if (empty($user_id) or empty($courseId) or empty($session_id)) {
3856
            return false;
3857
        }
3858
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3859
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
3860
        $sql = "SELECT session_rcru.status
3861
                FROM $tbl_session_rel_course_rel_user session_rcru, $tbl_user user
3862
                WHERE session_rcru.user_id = user.user_id AND
3863
                    session_rcru.session_id = '" . intval($session_id) . "' AND
3864
                    session_rcru.c_id ='" . intval($courseId) . "' AND
3865
                    user.user_id = " . intval($user_id);
3866
        $result = Database::query($sql);
3867
        $status = false;
3868
        if (Database::num_rows($result)) {
3869
            $status = Database::fetch_row($result);
3870
            $status = $status['0'];
3871
        }
3872
        return $status;
3873
    }
3874
3875
    /**
3876
     * @param int $id
3877
     * @return array
3878
     */
3879
    public static function get_all_sessions_by_promotion($id)
3880
    {
3881
        $t = Database::get_main_table(TABLE_MAIN_SESSION);
3882
        return Database::select('*', $t, array('where' => array('promotion_id = ?' => $id)));
3883
    }
3884
3885
    /**
3886
     * @param int $promotion_id
3887
     * @param array $list
3888
     */
3889
    public static function subscribe_sessions_to_promotion($promotion_id, $list)
3890
    {
3891
        $t = Database::get_main_table(TABLE_MAIN_SESSION);
3892
        $params = array();
3893
        $params['promotion_id'] = 0;
3894
        Database::update($t, $params, array('promotion_id = ?' => $promotion_id));
3895
3896
        $params['promotion_id'] = $promotion_id;
3897
        if (!empty($list)) {
3898
            foreach ($list as $session_id) {
3899
                $session_id = intval($session_id);
3900
                Database::update($t, $params, array('id = ?' => $session_id));
3901
            }
3902
        }
3903
    }
3904
3905
    /**
3906
     * Updates a session status
3907
     * @param	int 	session id
3908
     * @param	int 	status
3909
     */
3910
    public static function set_session_status($session_id, $status)
3911
    {
3912
        $t = Database::get_main_table(TABLE_MAIN_SESSION);
3913
        $params['visibility'] = $status;
3914
        Database::update($t, $params, array('id = ?' => $session_id));
3915
    }
3916
3917
    /**
3918
     * Copies a session with the same data to a new session.
3919
     * The new copy is not assigned to the same promotion. @see subscribe_sessions_to_promotions() for that
3920
     * @param   int     Session ID
3921
     * @param   bool    Whether to copy the relationship with courses
3922
     * @param   bool    Whether to copy the relationship with users
3923
     * @param   bool    New courses will be created
3924
     * @param   bool    Whether to set exercises and learning paths in the new session to invisible by default
3925
     * @return  int     The new session ID on success, 0 otherwise
3926
     * @todo make sure the extra session fields are copied too
3927
     */
3928
    public static function copy(
3929
        $id,
3930
        $copy_courses = true,
3931
        $copy_users = true,
3932
        $create_new_courses = false,
3933
        $set_exercises_lp_invisible = false
3934
    ) {
3935
        $id = intval($id);
3936
        $s = self::fetch($id);
3937
        // Check all dates before copying
3938
        // Get timestamp for now in UTC - see http://php.net/manual/es/function.time.php#117251
3939
        $now = time() - date('Z');
3940
        // Timestamp in one month
3941
        $inOneMonth = $now + (30*24*3600);
3942
        $inOneMonth = api_get_local_time($inOneMonth);
3943
        if (api_strtotime($s['access_start_date']) < $now) {
3944
            $s['access_start_date'] = api_get_local_time($now);
3945
        }
3946
        if (api_strtotime($s['display_start_date']) < $now) {
3947
            $s['display_start_date'] = api_get_local_time($now);
3948
        }
3949
        if (api_strtotime($s['coach_access_start_date']) < $now) {
3950
            $s['coach_access_start_date'] = api_get_local_time($now);
3951
        }
3952
        if (api_strtotime($s['access_end_date']) < $now) {
3953
            $s['access_end_date'] = $inOneMonth;
3954
        }
3955
        if (api_strtotime($s['display_end_date']) < $now) {
3956
            $s['display_end_date'] = $inOneMonth;
3957
        }
3958
        if (api_strtotime($s['coach_access_end_date']) < $now) {
3959
            $s['coach_access_end_date'] = $inOneMonth;
3960
        }
3961
        // Now try to create the session
3962
        $sid = self::create_session(
3963
            $s['name'] . ' ' . get_lang('CopyLabelSuffix'),
3964
            $s['access_start_date'],
3965
            $s['access_end_date'],
3966
            $s['display_start_date'],
3967
            $s['display_end_date'],
3968
            $s['coach_access_start_date'],
3969
            $s['coach_access_end_date'],
3970
            (int)$s['id_coach'],
3971
            $s['session_category_id'],
3972
            (int)$s['visibility'],
3973
            true
3974
        );
3975
3976
        if (!is_numeric($sid) || empty($sid)) {
3977
            return false;
3978
        }
3979
3980
        if ($copy_courses) {
3981
            // Register courses from the original session to the new session
3982
            $courses = self::get_course_list_by_session_id($id);
3983
3984
            $short_courses = $new_short_courses = array();
3985
            if (is_array($courses) && count($courses) > 0) {
3986
                foreach ($courses as $course) {
3987
                    $short_courses[] = $course;
3988
                }
3989
            }
3990
3991
            $courses = null;
3992
3993
            //We will copy the current courses of the session to new courses
3994
            if (!empty($short_courses)) {
3995
                if ($create_new_courses) {
3996
                    //Just in case
3997
                    if (function_exists('ini_set')) {
3998
                        api_set_memory_limit('256M');
3999
                        ini_set('max_execution_time', 0);
4000
                    }
4001
                    $params = array();
4002
                    $params['skip_lp_dates'] = true;
4003
4004
                    foreach ($short_courses as $course_data) {
4005
                        $course_info = CourseManager::copy_course_simple(
4006
                            $course_data['title'].' '.get_lang(
4007
                                'CopyLabelSuffix'
4008
                            ),
4009
                            $course_data['course_code'],
4010
                            $id,
4011
                            $sid,
4012
                            $params
4013
                        );
4014
4015
                        if ($course_info) {
4016
                            //By default new elements are invisible
4017
                            if ($set_exercises_lp_invisible) {
4018
                                $list = new LearnpathList('', $course_info['code'], $sid);
4019
                                $flat_list = $list->get_flat_list();
4020
                                if (!empty($flat_list)) {
4021
                                    foreach ($flat_list as $lp_id => $data) {
4022
                                        api_item_property_update(
4023
                                            $course_info,
4024
                                            TOOL_LEARNPATH,
4025
                                            $lp_id,
4026
                                            'invisible',
4027
                                            api_get_user_id(),
4028
                                            0,
4029
                                            0,
4030
                                            0,
4031
                                            0,
4032
                                            $sid
4033
                                        );
4034
                                    }
4035
                                }
4036
                                $quiz_table = Database::get_course_table(TABLE_QUIZ_TEST);
4037
                                $course_id = $course_info['real_id'];
4038
                                //@todo check this query
4039
                                $sql = "UPDATE $quiz_table SET active = 0
4040
                                        WHERE c_id = $course_id AND session_id = $sid";
4041
                                Database::query($sql);
4042
                            }
4043
                            $new_short_courses[] = $course_info['real_id'];
4044
                        }
4045
                    }
4046
                } else {
4047
                    foreach ($short_courses as $course_data) {
4048
                        $new_short_courses[] = $course_data['id'];
4049
                    }
4050
                }
4051
4052
                $short_courses = $new_short_courses;
4053
                self::add_courses_to_session($sid, $short_courses, true);
4054
                $short_courses = null;
4055
            }
4056
        }
4057
        if ($copy_users) {
4058
            // Register users from the original session to the new session
4059
            $users = self::get_users_by_session($id);
4060
            $short_users = array();
4061
            if (is_array($users) && count($users) > 0) {
4062
                foreach ($users as $user) {
4063
                    $short_users[] = $user['user_id'];
4064
                }
4065
            }
4066
            $users = null;
4067
            //Subscribing in read only mode
4068
            self::subscribe_users_to_session(
4069
                $sid,
4070
                $short_users,
4071
                SESSION_VISIBLE_READ_ONLY,
4072
                true
4073
            );
4074
            $short_users = null;
4075
        }
4076
        return $sid;
4077
    }
4078
4079
    /**
4080
     * @param int $user_id
4081
     * @param int $session_id
4082
     * @return bool
4083
     */
4084
    public static function user_is_general_coach($user_id, $session_id)
4085
    {
4086
        $session_id = intval($session_id);
4087
        $user_id = intval($user_id);
4088
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
4089
        $sql = "SELECT DISTINCT id
4090
	         	FROM $session_table
4091
	         	WHERE session.id_coach =  '" . $user_id . "' AND id = '$session_id'";
4092
        $result = Database::query($sql);
4093
        if ($result && Database::num_rows($result)) {
4094
            return true;
4095
        }
4096
        return false;
4097
    }
4098
4099
    /**
4100
     * Get the number of sessions
4101
     * @param  int ID of the URL we want to filter on (optional)
4102
     * @return int Number of sessions
4103
     */
4104 View Code Duplication
    public static function count_sessions($access_url_id = null)
4105
    {
4106
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
4107
        $access_url_rel_session_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4108
        $sql = "SELECT count(id) FROM $session_table s";
4109
        if (!empty($access_url_id) && $access_url_id == intval($access_url_id)) {
4110
            $sql .= ", $access_url_rel_session_table u " .
4111
                " WHERE s.id = u.session_id AND u.access_url_id = $access_url_id";
4112
        }
4113
        $res = Database::query($sql);
4114
        $row = Database::fetch_row($res);
4115
        return $row[0];
4116
    }
4117
4118
    /**
4119
     * Protect a session to be edited.
4120
     * @param int $id
4121
     * @param bool $checkSession
4122
     * @return mixed | bool true if pass the check, api_not_allowed otherwise
4123
     */
4124
    public static function protectSession($id, $checkSession = true)
4125
    {
4126
        // api_protect_admin_script(true);
4127
        if (self::allowToManageSessions()) {
4128
4129
            if (api_is_platform_admin() && self::allowed($id)) {
4130
                return true;
4131
            }
4132
4133
            if ($checkSession) {
4134
                if (self::allowed($id)) {
4135
                    return true;
4136
                } else {
4137
                    api_not_allowed(true);
4138
                }
4139
            }
4140
        } else {
4141
            api_not_allowed(true);
4142
        }
4143
    }
4144
4145
    /**
4146
     * @param int $id
4147
     * @return bool
4148
     */
4149
    private static function allowed($id)
4150
    {
4151
        $sessionInfo = self::fetch($id);
4152
4153
        if (empty($sessionInfo)) {
4154
            return false;
4155
        }
4156
4157
        if (api_is_platform_admin()) {
4158
            return true;
4159
        }
4160
4161
        $userId = api_get_user_id();
4162
4163
        if (api_is_session_admin() &&
4164
            api_get_setting('allow_session_admins_to_manage_all_sessions') != 'true'
4165
        ) {
4166
            if ($sessionInfo['session_admin_id'] != $userId) {
4167
                return false;
4168
            }
4169
        }
4170
4171
        if (api_is_teacher() &&
4172
            api_get_setting('allow_teachers_to_create_sessions') == 'true'
4173
        ) {
4174
            if ($sessionInfo['id_coach'] != $userId) {
4175
                return false;
4176
            }
4177
        }
4178
4179
        return true;
4180
    }
4181
4182
    /**
4183
     * @return bool
4184
     */
4185
    public static function allowToManageSessions()
4186
    {
4187
        if (self::allowManageAllSessions()) {
4188
            return true;
4189
        }
4190
4191
        $setting = api_get_setting('allow_teachers_to_create_sessions');
4192
4193
        if (api_is_teacher() && $setting == 'true') {
4194
4195
            return true;
4196
        }
4197
4198
        return false;
4199
    }
4200
4201
    /**
4202
     * @return bool
4203
     */
4204
    public static function allowOnlyMySessions()
4205
    {
4206
        if (self::allowToManageSessions() &&
4207
            !api_is_platform_admin() &&
4208
            api_is_teacher()
4209
        ) {
4210
            return true;
4211
        }
4212
4213
        return false;
4214
    }
4215
4216
    /**
4217
     * @return bool
4218
     */
4219
    public static function allowManageAllSessions()
4220
    {
4221
        if (api_is_platform_admin() || api_is_session_admin()) {
4222
            return true;
4223
        }
4224
4225
        return false;
4226
    }
4227
4228
    /**
4229
     * @param $id
4230
     * @return bool
4231
     */
4232
    public static function protect_teacher_session_edit($id)
4233
    {
4234
        if (!api_is_coach($id) && !api_is_platform_admin()) {
4235
            api_not_allowed(true);
4236
        } else {
4237
            return true;
4238
        }
4239
    }
4240
4241
    /**
4242
     * @param int $courseId
4243
     * @return array
4244
     */
4245
    public static function get_session_by_course($courseId)
4246
    {
4247
        $table_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4248
        $table_session = Database::get_main_table(TABLE_MAIN_SESSION);
4249
        $courseId = intval($courseId);
4250
        $sql = "SELECT name, s.id
4251
                FROM $table_session_course sc
4252
                INNER JOIN $table_session s ON (sc.session_id = s.id)
4253
                WHERE sc.c_id = '$courseId' ";
4254
        $result = Database::query($sql);
4255
4256
        return Database::store_result($result);
4257
    }
4258
4259
    /**
4260
     * @param int $user_id
4261
     * @param bool $ignoreVisibilityForAdmins
4262
     * @param bool $ignoreTimeLimit
4263
     *
4264
     * @return array
4265
     */
4266
    public static function get_sessions_by_user($user_id, $ignoreVisibilityForAdmins = false, $ignoreTimeLimit = false)
4267
    {
4268
        $sessionCategories = UserManager::get_sessions_by_category(
4269
            $user_id,
4270
            false,
4271
            $ignoreVisibilityForAdmins,
4272
            $ignoreTimeLimit
4273
        );
4274
4275
        $sessionArray = array();
4276
        if (!empty($sessionCategories)) {
4277
            foreach ($sessionCategories as $category) {
4278
                if (isset($category['sessions'])) {
4279
                    foreach ($category['sessions'] as $session) {
4280
                        $sessionArray[] = $session;
4281
                    }
4282
                }
4283
            }
4284
        }
4285
4286
        return $sessionArray;
4287
    }
4288
4289
    /**
4290
     * @param string $file
4291
     * @param bool $updateSession options:
4292
     *  true: if the session exists it will be updated.
4293
     *  false: if session exists a new session will be created adding a counter session1, session2, etc
4294
     * @param int $defaultUserId
4295
     * @param mixed $logger
4296
     * @param array $extraFields convert a file row to an extra field. Example in CSV file there's a SessionID then it will
4297
     * converted to extra_external_session_id if you set this: array('SessionId' => 'extra_external_session_id')
4298
     * @param string $extraFieldId
4299
     * @param int $daysCoachAccessBeforeBeginning
4300
     * @param int $daysCoachAccessAfterBeginning
4301
     * @param int $sessionVisibility
4302
     * @param array $fieldsToAvoidUpdate
4303
     * @param bool $deleteUsersNotInList
4304
     * @param bool $updateCourseCoaches
4305
     * @param bool $sessionWithCoursesModifier
4306
     * @param int $showDescription
4307
     * @param array $teacherBackupList
4308
     * @param array $groupBackup
4309
     * @return array
4310
     */
4311
    public static function importCSV(
4312
        $file,
4313
        $updateSession,
4314
        $defaultUserId = null,
4315
        $logger = null,
4316
        $extraFields = array(),
4317
        $extraFieldId = null,
4318
        $daysCoachAccessBeforeBeginning = null,
4319
        $daysCoachAccessAfterBeginning = null,
4320
        $sessionVisibility = 1,
4321
        $fieldsToAvoidUpdate = array(),
4322
        $deleteUsersNotInList = false,
4323
        $updateCourseCoaches = false,
4324
        $sessionWithCoursesModifier = false,
4325
        $addOriginalCourseTeachersAsCourseSessionCoaches = true,
4326
        $removeAllTeachersFromCourse = true,
4327
        $showDescription = null,
4328
        &$teacherBackupList = array(),
4329
        &$groupBackup = array()
4330
    ) {
4331
        $content = file($file);
4332
4333
        $error_message = null;
4334
        $session_counter = 0;
4335
        $defaultUserId = empty($defaultUserId) ? api_get_user_id() : (int) $defaultUserId;
4336
4337
        $eol = PHP_EOL;
4338
        if (PHP_SAPI != 'cli') {
4339
            $eol = '<br />';
4340
        }
4341
4342
        $debug = false;
4343
        if (isset($logger)) {
4344
            $debug = true;
4345
        }
4346
4347
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
4348
        $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
4349
        $tbl_session_course  = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4350
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
4351
4352
        $sessions = array();
4353
4354
        if (!api_strstr($content[0], ';')) {
4355
            $error_message = get_lang('NotCSV');
4356
        } else {
4357
            $tag_names = array();
4358
4359
            foreach ($content as $key => $enreg) {
4360
                $enreg = explode(';', trim($enreg));
4361 View Code Duplication
                if ($key) {
4362
                    foreach ($tag_names as $tag_key => $tag_name) {
4363
                        if (isset($enreg[$tag_key])) {
4364
                            $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
4365
                        }
4366
                    }
4367
                } else {
4368
                    foreach ($enreg as $tag_name) {
4369
                        $tag_names[] = api_preg_replace('/[^a-zA-Z0-9_\-]/', '', $tag_name);
4370
                    }
4371
                    if (!in_array('SessionName', $tag_names) ||
4372
                        !in_array('DateStart', $tag_names) ||
4373
                        !in_array('DateEnd', $tag_names)
4374
                    ) {
4375
                        $error_message = get_lang('NoNeededData');
4376
                        break;
4377
                    }
4378
                }
4379
            }
4380
4381
            $sessionList = array();
4382
            // Looping the sessions.
4383
            foreach ($sessions as $enreg) {
4384
                $user_counter = 0;
4385
                $course_counter = 0;
4386
4387
                if (isset($extraFields) && !empty($extraFields)) {
4388
                    foreach ($extraFields as $original => $to) {
4389
                        $enreg[$to] = isset($enreg[$original]) ? $enreg[$original] : null;
4390
                    }
4391
                }
4392
4393
                $session_name = $enreg['SessionName'];
4394
                // Default visibility
4395
                $visibilityAfterExpirationPerSession = $sessionVisibility;
4396
4397
                if (isset($enreg['VisibilityAfterExpiration'])) {
4398
                    $visibility = $enreg['VisibilityAfterExpiration'];
4399
                    switch ($visibility) {
4400
                        case 'read_only':
4401
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE_READ_ONLY;
4402
                            break;
4403
                        case 'accessible':
4404
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE;
4405
                            break;
4406
                        case 'not_accessible':
4407
                            $visibilityAfterExpirationPerSession = SESSION_INVISIBLE;
4408
                            break;
4409
                    }
4410
                }
4411
4412
                if (empty($session_name)) {
4413
                    continue;
4414
                }
4415
4416
                // We assume the dates are already in UTC
4417
                $dateStart = explode('/', $enreg['DateStart']);
4418
                $dateEnd = explode('/', $enreg['DateEnd']);
4419
                $dateStart = $dateStart[0].'-'.$dateStart[1].'-'.$dateStart[2].' 00:00:00';
4420
                $dateEnd = $dateEnd[0].'-'.$dateEnd[1].'-'.$dateEnd[2].' 23:59:59';
4421
4422
                $session_category_id = isset($enreg['SessionCategory']) ? $enreg['SessionCategory'] : null;
4423
                $sessionDescription = isset($enreg['SessionDescription']) ? $enreg['SessionDescription'] : null;
4424
4425
                $extraParameters = null;
4426
                if (!is_null($showDescription)) {
4427
                    $extraParameters .= ' , show_description = '.intval($showDescription);
4428
                }
4429
4430
                $coachBefore = '';
4431
                $coachAfter = '';
4432
4433
                if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
4434
                    $date = new \DateTime($dateStart);
4435
                    $interval = new DateInterval(
4436
                        'P'.$daysCoachAccessBeforeBeginning.'D'
4437
                    );
4438
                    $date->sub($interval);
4439
                    $coachBefore = $date->format('Y-m-d h:i');
4440
                    $coachBefore = api_get_utc_datetime($coachBefore);
4441
4442
                    $extraParameters .= " , coach_access_start_date = '$coachBefore'";
4443
4444
                    $date = new \DateTime($dateEnd);
4445
                    $interval = new DateInterval('P'.$daysCoachAccessAfterBeginning.'D');
4446
                    $date->add($interval);
4447
                    $coachAfter = $date->format('Y-m-d h:i');
4448
4449
                    $coachAfter = api_get_utc_datetime($coachAfter);
4450
                    $extraParameters .= " , coach_access_end_date = '$coachAfter'";
4451
                }
4452
4453
                $dateStart = api_get_utc_datetime($dateStart);
4454
                $dateEnd = api_get_utc_datetime($dateEnd);
4455
4456
                $extraSessionParameters = null;
4457
                if (!empty($sessionDescription)) {
4458
                    $extraSessionParameters = " , description = '".Database::escape_string($sessionDescription)."'";
4459
                }
4460
4461
                $sessionCondition = '';
4462
                if (!empty($session_category_id)) {
4463
                    $sessionCondition = " , session_category_id = '$session_category_id' ";
4464
                }
4465
4466
                // Searching a general coach.
4467
                if (!empty($enreg['Coach'])) {
4468
                    $coach_id = UserManager::get_user_id_from_username($enreg['Coach']);
4469
                    if ($coach_id === false) {
4470
                        // If the coach-user does not exist - I'm the coach.
4471
                        $coach_id = $defaultUserId;
4472
                    }
4473
                } else {
4474
                    $coach_id = $defaultUserId;
4475
                }
4476
4477
                $users = explode('|', $enreg['Users']);
4478
                $courses = explode('|', $enreg['Courses']);
4479
4480
                $deleteOnlyCourseCoaches = false;
4481
                if (count($courses) == 1) {
4482
                    if ($logger) {
4483
                        $logger->addInfo('Only one course delete old coach list');
4484
                    }
4485
                    $deleteOnlyCourseCoaches = true;
4486
                }
4487
4488
                if (!$updateSession) {
4489
                    // Always create a session.
4490
                    $unique_name = false;
4491
                    $i = 0;
4492
                    // Change session name, verify that session doesn't exist.
4493
                    $suffix = null;
4494 View Code Duplication
                    while (!$unique_name) {
4495
                        if ($i > 1) {
4496
                            $suffix = ' - ' . $i;
4497
                        }
4498
                        $sql = 'SELECT 1 FROM ' . $tbl_session . '
4499
                                WHERE name="' . Database::escape_string($session_name). $suffix . '"';
4500
                        $rs = Database::query($sql);
4501
4502
                        if (Database::result($rs, 0, 0)) {
4503
                            $i++;
4504
                        } else {
4505
                            $unique_name = true;
4506
                            $session_name .= $suffix;
4507
                        }
4508
                    }
4509
4510
                    // Creating the session.
4511
                    $sql = "INSERT IGNORE INTO $tbl_session SET
4512
                            name = '" . Database::escape_string($session_name). "',
4513
                            id_coach = '$coach_id',
4514
                            access_start_date = '$dateStart',
4515
                            access_end_date = '$dateEnd',
4516
                            display_start_date = '$dateStart',
4517
                            display_end_date = '$dateEnd',
4518
                            visibility = '$visibilityAfterExpirationPerSession',                            
4519
                            session_admin_id = " . $defaultUserId . " 
4520
                            $sessionCondition $extraParameters $extraSessionParameters";
4521
                    Database::query($sql);
4522
4523
                    $session_id = Database::insert_id();
4524
                    if ($debug) {
4525
                        if ($session_id) {
4526 View Code Duplication
                            foreach ($enreg as $key => $value) {
4527
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
4528
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
4529
                                }
4530
                            }
4531
4532
                            $logger->addInfo("Sessions - Session created: #$session_id - $session_name");
4533
                        } else {
4534
                            $logger->addError("Sessions - Session NOT created: $session_name");
4535
                        }
4536
                    }
4537
                    $session_counter++;
4538
                } else {
4539
                    $sessionId = null;
4540
                    if (isset($extraFields) && !empty($extraFields) && !empty($enreg['extra_'.$extraFieldId])) {
4541
                        $sessionId = self::getSessionIdFromOriginalId($enreg['extra_'.$extraFieldId], $extraFieldId);
4542
                        if (empty($sessionId)) {
4543
                            $my_session_result = false;
4544
                        } else {
4545
                            $my_session_result = true;
4546
                        }
4547
                    } else {
4548
                        $my_session_result = self::get_session_by_name($enreg['SessionName']);
4549
                    }
4550
4551
                    if ($my_session_result === false) {
4552
4553
                        // Creating a session.
4554
                        $sql = "INSERT IGNORE INTO $tbl_session SET
4555
                                name = '$session_name',
4556
                                id_coach = '$coach_id',
4557
                                access_start_date = '$dateStart',
4558
                                access_end_date = '$dateEnd',
4559
                                display_start_date = '$dateStart',
4560
                                display_end_date = '$dateEnd',
4561
                                visibility = '$visibilityAfterExpirationPerSession' 
4562
                                $extraParameters 
4563
                                $extraSessionParameters
4564
                                $sessionCondition
4565
                                ";
4566
4567
                        Database::query($sql);
4568
4569
                        // We get the last insert id.
4570
                        $my_session_result = self::get_session_by_name($enreg['SessionName']);
4571
                        $session_id = $my_session_result['id'];
4572
4573
                        if ($session_id) {
4574 View Code Duplication
                            foreach ($enreg as $key => $value) {
4575
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
4576
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
4577
                                }
4578
                            }
4579
                            if ($debug) {
4580
                                $logger->addInfo("Sessions - #$session_id created: $session_name");
4581
                            }
4582
4583
                            // Delete session-user relation only for students
4584
                            $sql = "DELETE FROM $tbl_session_user
4585
                                    WHERE session_id = '$session_id' AND relation_type <> " . SESSION_RELATION_TYPE_RRHH;
4586
                            Database::query($sql);
4587
4588
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
4589
                            Database::query($sql);
4590
4591
                            // Delete session-course-user relationships students and coaches.
4592 View Code Duplication
                            if ($updateCourseCoaches) {
4593
                                $sql = "DELETE FROM $tbl_session_course_user
4594
                                        WHERE session_id = '$session_id' AND status in ('0', '2')";
4595
                                Database::query($sql);
4596
                            } else {
4597
                                // Delete session-course-user relation ships *only* for students.
4598
                                $sql = "DELETE FROM $tbl_session_course_user
4599
                                        WHERE session_id = '$session_id' AND status <> 2";
4600
                                Database::query($sql);
4601
                            }
4602
                            if ($deleteOnlyCourseCoaches) {
4603
                                $sql = "DELETE FROM $tbl_session_course_user
4604
                                        WHERE session_id = '$session_id' AND status in ('2')";
4605
                                Database::query($sql);
4606
                            }
4607
                        }
4608
                    } else {
4609
                        // Updating the session.
4610
                        $params = array(
4611
                            'id_coach' => $coach_id,
4612
                            'access_start_date' => $dateStart,
4613
                            'access_end_date' => $dateEnd,
4614
                            'display_start_date' => $dateStart,
4615
                            'display_end_date' => $dateEnd,
4616
                            'visibility' => $visibilityAfterExpirationPerSession,
4617
                            'session_category_id' => $session_category_id,
4618
                        );
4619
4620
                        if (!empty($sessionDescription)) {
4621
                            $params['description'] = $sessionDescription;
4622
                        }
4623
4624
                        if (!empty($fieldsToAvoidUpdate)) {
4625
                            foreach ($fieldsToAvoidUpdate as $field) {
4626
                                unset($params[$field]);
4627
                            }
4628
                        }
4629
4630
                        if (isset($sessionId) && !empty($sessionId)) {
4631
                            $session_id = $sessionId;
4632
                            if (!empty($enreg['SessionName'])) {
4633
                                $sessionName = Database::escape_string($enreg['SessionName']);
4634
                                $sql = "UPDATE $tbl_session SET name = '$sessionName' WHERE id = $session_id";
4635
                                Database::query($sql);
4636
                            }
4637
                        } else {
4638
                            $my_session_result = self::get_session_by_name($session_name);
4639
                            $session_id = $my_session_result['id'];
4640
                        }
4641
4642
                        if ($debug) {
4643
                            $logger->addError("Sessions - Session #$session_id to be updated: '$session_name'");
4644
                        }
4645
4646
                        if ($session_id) {
4647
                            if ($debug) {
4648
                                $logger->addError("Sessions - Session to be updated #$session_id");
4649
                            }
4650
4651
                            $sessionInfo = api_get_session_info($session_id);
4652
                            $params['show_description'] = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : intval($showDescription);
4653
4654
                            if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
4655 View Code Duplication
                                if (empty($sessionInfo['nb_days_access_before_beginning']) ||
4656
                                    (!empty($sessionInfo['nb_days_access_before_beginning']) &&
4657
                                        $sessionInfo['nb_days_access_before_beginning'] < $daysCoachAccessBeforeBeginning)
4658
                                ) {
4659
                                    $params['coach_access_start_date'] = $coachBefore;
4660
                                }
4661
4662 View Code Duplication
                                if (empty($sessionInfo['nb_days_access_after_end']) ||
4663
                                    (!empty($sessionInfo['nb_days_access_after_end']) &&
4664
                                        $sessionInfo['nb_days_access_after_end'] < $daysCoachAccessAfterBeginning)
4665
                                ) {
4666
                                    $params['coach_access_end_date'] = $coachAfter;
4667
                                }
4668
                            }
4669
4670
                            Database::update($tbl_session, $params, array('id = ?' => $session_id));
4671
4672 View Code Duplication
                            foreach ($enreg as $key => $value) {
4673
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
4674
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
4675
                                }
4676
                            }
4677
4678
                            // Delete session-user relation only for students
4679
                            $sql = "DELETE FROM $tbl_session_user
4680
                                    WHERE session_id = '$session_id' AND relation_type <> " . SESSION_RELATION_TYPE_RRHH;
4681
                            Database::query($sql);
4682
4683
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
4684
                            Database::query($sql);
4685
4686
                            // Delete session-course-user relationships students and coaches.
4687 View Code Duplication
                            if ($updateCourseCoaches) {
4688
                                $sql = "DELETE FROM $tbl_session_course_user
4689
                                        WHERE session_id = '$session_id' AND status in ('0', '2')";
4690
                                Database::query($sql);
4691
                            } else {
4692
                                // Delete session-course-user relation ships *only* for students.
4693
                                $sql = "DELETE FROM $tbl_session_course_user
4694
                                        WHERE session_id = '$session_id' AND status <> 2";
4695
                                Database::query($sql);
4696
                            }
4697
4698
                            if ($deleteOnlyCourseCoaches) {
4699
                                $sql = "DELETE FROM $tbl_session_course_user
4700
                                        WHERE session_id = '$session_id' AND status in ('2')";
4701
                                Database::query($sql);
4702
                            }
4703
                        } else {
4704
                            if ($debug) {
4705
                                $logger->addError(
4706
                                    "Sessions - Session not found"
4707
                                );
4708
                            }
4709
                        }
4710
                    }
4711
                    $session_counter++;
4712
                }
4713
4714
                $sessionList[] = $session_id;
4715
4716
                // Adding the relationship "Session - User" for students
4717
                $userList = array();
4718
                if (is_array($users)) {
4719
                    foreach ($users as $user) {
4720
                        $user_id = UserManager::get_user_id_from_username($user);
4721
                        if ($user_id !== false) {
4722
                            $userList[] = $user_id;
4723
                            // Insert new users.
4724
                            $sql = "INSERT IGNORE INTO $tbl_session_user SET
4725
                                    user_id = '$user_id',
4726
                                    session_id = '$session_id',
4727
                                    registered_at = '" . api_get_utc_datetime() . "'";
4728
                            Database::query($sql);
4729
                            if ($debug) {
4730
                                $logger->addInfo("Sessions - Adding User #$user_id ($user) to session #$session_id");
4731
                            }
4732
                            $user_counter++;
4733
                        }
4734
                    }
4735
                }
4736
4737
                if ($deleteUsersNotInList) {
4738
                    // Getting user in DB in order to compare to the new list.
4739
                    $usersListInDatabase = self::get_users_by_session($session_id, 0);
4740
4741
                    if (!empty($usersListInDatabase)) {
4742
                        if (empty($userList)) {
4743
                            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...
4744
                                self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
4745
                            }
4746
                        } else {
4747
                            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...
4748
                                if (!in_array($userInfo['user_id'], $userList)) {
4749
                                    self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
4750
                                }
4751
                            }
4752
                        }
4753
                    }
4754
                }
4755
4756
4757
                // See BT#6449
4758
                $onlyAddFirstCoachOrTeacher = false;
4759
4760
                if ($sessionWithCoursesModifier) {
4761
                    if (count($courses) >= 2) {
4762
                        // Only first teacher in course session;
4763
                        $onlyAddFirstCoachOrTeacher = true;
4764
4765
                        // Remove all teachers from course.
4766
                        $removeAllTeachersFromCourse = false;
4767
                    }
4768
                }
4769
4770
                foreach ($courses as $course) {
4771
                    $courseArray = bracketsToArray($course);
4772
                    $course_code = $courseArray[0];
4773
4774
                    if (CourseManager::course_exists($course_code)) {
4775
                        $courseInfo = api_get_course_info($course_code);
4776
                        $courseId = $courseInfo['real_id'];
4777
4778
                        // Adding the course to a session.
4779
                        $sql = "INSERT IGNORE INTO $tbl_session_course
4780
                                SET c_id = '$courseId', session_id='$session_id'";
4781
                        Database::query($sql);
4782
4783
                        self::installCourse($session_id, $courseInfo['real_id']);
4784
4785
                        if ($debug) {
4786
                            $logger->addInfo("Sessions - Adding course '$course_code' to session #$session_id");
4787
                        }
4788
4789
                        $course_counter++;
4790
4791
                        $course_coaches = isset($courseArray[1]) ? $courseArray[1] : null;
4792
                        $course_users   = isset($courseArray[2]) ? $courseArray[2] : null;
4793
4794
                        $course_users   = explode(',', $course_users);
4795
                        $course_coaches = explode(',', $course_coaches);
4796
4797
                        // Checking if the flag is set TeachersWillBeAddedAsCoachInAllCourseSessions (course_edit.php)
4798
                        $addTeachersToSession = true;
4799
4800
                        if (array_key_exists('add_teachers_to_sessions_courses', $courseInfo)) {
4801
                            $addTeachersToSession = $courseInfo['add_teachers_to_sessions_courses'];
4802
                        }
4803
4804
                        // If any user provided for a course, use the users array.
4805
                        if (empty($course_users)) {
4806
                            if (!empty($userList)) {
4807
                                self::subscribe_users_to_session_course(
4808
                                    $userList,
4809
                                    $session_id,
4810
                                    $course_code
4811
                                );
4812
                                if ($debug) {
4813
                                    $msg = "Sessions - Adding student list ".implode(', #', $userList)." to course: '$course_code' and session #$session_id";
4814
                                    $logger->addInfo($msg);
4815
                                }
4816
                            }
4817
                        }
4818
4819
                        // Adding coaches to session course user.
4820
                        if (!empty($course_coaches)) {
4821
                            $savedCoaches = array();
4822
                            // only edit if add_teachers_to_sessions_courses is set.
4823
                            if ($addTeachersToSession) {
4824
                                if ($addOriginalCourseTeachersAsCourseSessionCoaches) {
4825
                                    // Adding course teachers as course session teachers.
4826
                                    $alreadyAddedTeachers = CourseManager::get_teacher_list_from_course_code(
4827
                                        $course_code
4828
                                    );
4829
4830
                                    if (!empty($alreadyAddedTeachers)) {
4831
                                        $teachersToAdd = array();
4832
                                        foreach ($alreadyAddedTeachers as $user) {
4833
                                            $teachersToAdd[] = $user['username'];
4834
                                        }
4835
                                        $course_coaches = array_merge(
4836
                                            $course_coaches,
4837
                                            $teachersToAdd
4838
                                        );
4839
                                    }
4840
                                }
4841
4842 View Code Duplication
                                foreach ($course_coaches as $course_coach) {
4843
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
4844
                                    if ($coach_id !== false) {
4845
                                        // Just insert new coaches
4846
                                        self::updateCoaches(
4847
                                            $session_id,
4848
                                            $courseId,
4849
                                            array($coach_id),
4850
                                            false
4851
                                        );
4852
4853
                                        if ($debug) {
4854
                                            $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
4855
                                        }
4856
                                        $savedCoaches[] = $coach_id;
4857
                                    } else {
4858
                                        $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
4859
                                    }
4860
                                }
4861
                            }
4862
4863
                            // Custom courses/session coaches
4864
                            $teacherToAdd = null;
4865
                            // Only one coach is added.
4866
                            if ($onlyAddFirstCoachOrTeacher == true) {
4867
                                if ($debug) {
4868
                                    $logger->addInfo("onlyAddFirstCoachOrTeacher : true");
4869
                                }
4870
4871 View Code Duplication
                                foreach ($course_coaches as $course_coach) {
4872
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
4873
                                    if ($coach_id !== false) {
4874
                                        $teacherToAdd = $coach_id;
4875
                                        break;
4876
                                    }
4877
                                }
4878
4879
                                // Un subscribe everyone that's not in the list.
4880
                                $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
4881 View Code Duplication
                                if (!empty($teacherList)) {
4882
                                    foreach ($teacherList as $teacher) {
4883
                                        if ($teacherToAdd != $teacher['user_id']) {
4884
                                            $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
4885
                                                    WHERE
4886
                                                        user_id = ".$teacher['user_id']." AND
4887
                                                        c_id = '".$courseId."'
4888
                                                    ";
4889
4890
                                            $result = Database::query($sql);
4891
                                            $rows = Database::num_rows($result);
4892
                                            if ($rows > 0) {
4893
                                                $userCourseData = Database::fetch_array($result, 'ASSOC');
4894
                                                if (!empty($userCourseData)) {
4895
                                                    $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
4896
                                                }
4897
                                            }
4898
4899
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
4900
                                                    WHERE
4901
                                                        user_id = ".$teacher['user_id']." AND
4902
                                                        c_id = '".$courseInfo['real_id']."'
4903
                                                    ";
4904
4905
                                            $result = Database::query($sql);
4906
                                            while ($groupData = Database::fetch_array($result, 'ASSOC')) {
4907
                                                $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
4908
                                            }
4909
4910
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
4911
                                                    WHERE
4912
                                                        user_id = ".$teacher['user_id']." AND
4913
                                                        c_id = '".$courseInfo['real_id']."'
4914
                                                    ";
4915
4916
                                            $result = Database::query($sql);
4917
                                            while ($groupData = Database::fetch_array($result, 'ASSOC')) {
4918
                                                $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
4919
                                            }
4920
4921
                                            CourseManager::unsubscribe_user(
4922
                                                $teacher['user_id'],
4923
                                                $course_code
4924
                                            );
4925
4926
                                            if ($debug) {
4927
                                                $logger->addInfo("Delete user #".$teacher['user_id']." from base course: $course_code");
4928
                                            }
4929
                                        }
4930
                                    }
4931
                                }
4932
4933
                                if (!empty($teacherToAdd)) {
4934
                                    self::updateCoaches(
4935
                                        $session_id,
4936
                                        $courseId,
4937
                                        array($teacherToAdd),
4938
                                        true
4939
                                    );
4940
4941
                                    if ($debug) {
4942
                                        $logger->addInfo("Add coach #$teacherToAdd to course $courseId and session $session_id");
4943
                                    }
4944
4945
                                    $userCourseCategory = '';
4946 View Code Duplication
                                    if (isset($teacherBackupList[$teacherToAdd]) &&
4947
                                        isset($teacherBackupList[$teacherToAdd][$course_code])
4948
                                    ) {
4949
                                        $courseUserData = $teacherBackupList[$teacherToAdd][$course_code];
4950
                                        $userCourseCategory = $courseUserData['user_course_cat'];
4951
                                    }
4952
4953
                                    CourseManager::subscribe_user(
4954
                                        $teacherToAdd,
4955
                                        $course_code,
4956
                                        COURSEMANAGER,
4957
                                        0,
4958
                                        $userCourseCategory
4959
                                    );
4960
4961
                                    if ($debug) {
4962
                                        $logger->addInfo("Subscribe user #$teacherToAdd as teacher in course $course_code with user userCourseCategory $userCourseCategory");
4963
                                    }
4964
4965 View Code Duplication
                                    if (isset($groupBackup['user'][$teacherToAdd]) &&
4966
                                        isset($groupBackup['user'][$teacherToAdd][$course_code]) &&
4967
                                        !empty($groupBackup['user'][$teacherToAdd][$course_code])
4968
                                    ) {
4969
                                        foreach ($groupBackup['user'][$teacherToAdd][$course_code] as $data) {
4970
                                            $groupInfo = GroupManager::get_group_properties($data['group_id']);
4971
                                            GroupManager::subscribe_users(
4972
                                                $teacherToAdd,
4973
                                                $groupInfo,
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by \GroupManager::get_group...ties($data['group_id']) on line 4970 can also be of type null; however, GroupManager::subscribe_users() does only seem to accept array, maybe add an additional type check?

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

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

    return array();
}

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

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

Loading history...
4974
                                                $data['c_id']
4975
                                            );
4976
                                        }
4977
                                    }
4978
4979 View Code Duplication
                                    if (isset($groupBackup['tutor'][$teacherToAdd]) &&
4980
                                        isset($groupBackup['tutor'][$teacherToAdd][$course_code]) &&
4981
                                        !empty($groupBackup['tutor'][$teacherToAdd][$course_code])
4982
                                    ) {
4983
                                        foreach ($groupBackup['tutor'][$teacherToAdd][$course_code] as $data) {
4984
                                            $groupInfo = GroupManager::get_group_properties($data['group_id']);
4985
                                            GroupManager::subscribe_tutors(
4986
                                                $teacherToAdd,
4987
                                                $groupInfo,
4988
                                                $data['c_id']
4989
                                            );
4990
                                        }
4991
                                    }
4992
                                }
4993
                            }
4994
4995
                            // See BT#6449#note-195
4996
                            // All coaches are added.
4997
                            if ($removeAllTeachersFromCourse) {
4998
                                if ($debug) {
4999
                                    $logger->addInfo("removeAllTeachersFromCourse true");
5000
                                }
5001
                                $teacherToAdd = null;
5002 View Code Duplication
                                foreach ($course_coaches as $course_coach) {
5003
                                    $coach_id = UserManager::get_user_id_from_username(
5004
                                        $course_coach
5005
                                    );
5006
                                    if ($coach_id !== false) {
5007
                                        $teacherToAdd[] = $coach_id;
5008
                                    }
5009
                                }
5010
5011
                                if (!empty($teacherToAdd)) {
5012
                                    // Deleting all course teachers and adding the only coach as teacher.
5013
                                    $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
5014
5015 View Code Duplication
                                    if (!empty($teacherList)) {
5016
                                        foreach ($teacherList as $teacher) {
5017
                                            if (!in_array($teacher['user_id'], $teacherToAdd)) {
5018
                                                $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
5019
                                                        WHERE
5020
                                                            user_id = ".$teacher['user_id']." AND
5021
                                                            c_id = '".$courseId."'
5022
                                                        ";
5023
5024
                                                $result = Database::query($sql);
5025
                                                $rows = Database::num_rows($result);
5026
                                                if ($rows > 0) {
5027
                                                    $userCourseData = Database::fetch_array($result, 'ASSOC');
5028
                                                    if (!empty($userCourseData)) {
5029
                                                        $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
5030
                                                    }
5031
                                                }
5032
5033
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
5034
                                                        WHERE
5035
                                                            user_id = ".$teacher['user_id']." AND
5036
                                                            c_id = '".$courseInfo['real_id']."'
5037
                                                        ";
5038
5039
                                                $result = Database::query($sql);
5040
                                                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5041
                                                    $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5042
                                                }
5043
5044
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
5045
                                                        WHERE
5046
                                                            user_id = ".$teacher['user_id']." AND
5047
                                                            c_id = '".$courseInfo['real_id']."'
5048
                                                        ";
5049
5050
                                                $result = Database::query($sql);
5051
                                                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5052
                                                    $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5053
                                                }
5054
5055
                                                CourseManager::unsubscribe_user(
5056
                                                    $teacher['user_id'],
5057
                                                    $course_code
5058
                                                );
5059
5060
                                                if ($debug) {
5061
                                                    $logger->addInfo("Delete user #".$teacher['user_id']." from base course: $course_code");
5062
                                                }
5063
                                            }
5064
                                        }
5065
                                    }
5066
5067
                                    foreach ($teacherToAdd as $teacherId) {
5068
                                        $userCourseCategory = '';
5069 View Code Duplication
                                        if (isset($teacherBackupList[$teacherId]) &&
5070
                                            isset($teacherBackupList[$teacherId][$course_code])
5071
                                        ) {
5072
                                            $courseUserData = $teacherBackupList[$teacherId][$course_code];
5073
                                            $userCourseCategory = $courseUserData['user_course_cat'];
5074
                                        }
5075
5076
                                        CourseManager::subscribe_user(
5077
                                            $teacherId,
5078
                                            $course_code,
5079
                                            COURSEMANAGER,
5080
                                            0,
5081
                                            $userCourseCategory
5082
                                        );
5083
5084
                                        if ($debug) {
5085
                                            $logger->addInfo("Add user as teacher #".$teacherId." in base course: $course_code with userCourseCategory: $userCourseCategory");
5086
                                        }
5087
5088 View Code Duplication
                                        if (isset($groupBackup['user'][$teacherId]) &&
5089
                                            isset($groupBackup['user'][$teacherId][$course_code]) &&
5090
                                            !empty($groupBackup['user'][$teacherId][$course_code])
5091
                                        ) {
5092
                                            foreach ($groupBackup['user'][$teacherId][$course_code] as $data) {
5093
                                                $groupInfo = GroupManager::get_group_properties($data['group_id']);
5094
                                                GroupManager::subscribe_users(
5095
                                                    $teacherId,
5096
                                                    $groupInfo,
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by \GroupManager::get_group...ties($data['group_id']) on line 5093 can also be of type null; however, GroupManager::subscribe_users() does only seem to accept array, maybe add an additional type check?

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

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

    return array();
}

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

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

Loading history...
5097
                                                    $data['c_id']
5098
                                                );
5099
                                            }
5100
                                        }
5101
5102 View Code Duplication
                                        if (isset($groupBackup['tutor'][$teacherId]) &&
5103
                                            isset($groupBackup['tutor'][$teacherId][$course_code]) &&
5104
                                            !empty($groupBackup['tutor'][$teacherId][$course_code])
5105
                                        ) {
5106
                                            foreach ($groupBackup['tutor'][$teacherId][$course_code] as $data) {
5107
                                                $groupInfo = GroupManager::get_group_properties($data['group_id']);
5108
                                                GroupManager::subscribe_tutors(
5109
                                                    $teacherId,
5110
                                                    $groupInfo,
5111
                                                    $data['c_id']
5112
                                                );
5113
                                            }
5114
                                        }
5115
                                    }
5116
                                }
5117
                            }
5118
5119
                            // Continue default behaviour.
5120
                            if ($onlyAddFirstCoachOrTeacher == false) {
5121
                                // Checking one more time see BT#6449#note-149
5122
                                $coaches = self::getCoachesByCourseSession($session_id, $courseId);
5123
                                // Update coaches if only there's 1 course see BT#6449#note-189
5124
                                if (empty($coaches) || count($courses) == 1) {
5125 View Code Duplication
                                    foreach ($course_coaches as $course_coach) {
5126
                                        $course_coach = trim($course_coach);
5127
                                        $coach_id = UserManager::get_user_id_from_username($course_coach);
5128
                                        if ($coach_id !== false) {
5129
                                            // Just insert new coaches
5130
                                            self::updateCoaches(
5131
                                                $session_id,
5132
                                                $courseId,
5133
                                                array($coach_id),
5134
                                                false
5135
                                            );
5136
5137
                                            if ($debug) {
5138
                                                $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
5139
                                            }
5140
                                            $savedCoaches[] = $coach_id;
5141
                                        } else {
5142
                                            $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
5143
                                        }
5144
                                    }
5145
                                }
5146
                            }
5147
                        }
5148
5149
                        // Adding Students, updating relationship "Session - Course - User".
5150
                        $course_users = array_filter($course_users);
5151
5152
                        if (!empty($course_users)) {
5153 View Code Duplication
                            foreach ($course_users as $user) {
5154
                                $user_id = UserManager::get_user_id_from_username($user);
5155
5156
                                if ($user_id !== false) {
5157
                                    self::subscribe_users_to_session_course(
5158
                                        array($user_id),
5159
                                        $session_id,
5160
                                        $course_code
5161
                                    );
5162
                                    if ($debug) {
5163
                                        $logger->addInfo("Sessions - Adding student: user #$user_id ($user) to course: '$course_code' and session #$session_id");
5164
                                    }
5165
                                } else {
5166
                                    $error_message .= get_lang('UserDoesNotExist').': '.$user.$eol;
5167
                                }
5168
                            }
5169
                        }
5170
5171
                        $inserted_in_course[$course_code] = $courseInfo['title'];
5172
                    }
5173
                }
5174
                $access_url_id = api_get_current_access_url_id();
5175
                UrlManager::add_session_to_url($session_id, $access_url_id);
5176
                $sql = "UPDATE $tbl_session SET nbr_users = '$user_counter', nbr_courses = '$course_counter' 
5177
                        WHERE id = '$session_id'";
5178
                Database::query($sql);
5179
            }
5180
        }
5181
5182
        return array(
5183
            'error_message' => $error_message,
5184
            'session_counter' => $session_counter,
5185
            'session_list' => $sessionList,
5186
        );
5187
    }
5188
5189
    /**
5190
     * @param int $sessionId
5191
     * @param int $courseId
5192
     * @return array
5193
     */
5194 View Code Duplication
    public static function getCoachesByCourseSession($sessionId, $courseId)
5195
    {
5196
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5197
        $sessionId = intval($sessionId);
5198
        $courseId = intval($courseId);
5199
5200
        $sql = "SELECT user_id FROM $table
5201
                WHERE
5202
                    session_id = '$sessionId' AND
5203
                    c_id = '$courseId' AND
5204
                    status = 2";
5205
        $result = Database::query($sql);
5206
5207
        $coaches = array();
5208
        if (Database::num_rows($result) > 0) {
5209
            while ($row = Database::fetch_array($result)) {
5210
                $coaches[] = $row['user_id'];
5211
            }
5212
        }
5213
5214
        return $coaches;
5215
    }
5216
5217
    /**
5218
     * @param int $sessionId
5219
     * @param int $courseId
5220
     * @return string
5221
     */
5222
    public static function getCoachesByCourseSessionToString(
5223
        $sessionId,
5224
        $courseId
5225
    ) {
5226
        $coaches = self::getCoachesByCourseSession($sessionId, $courseId);
5227
        $list = array();
5228 View Code Duplication
        if (!empty($coaches)) {
5229
            foreach ($coaches as $coachId) {
5230
                $userInfo = api_get_user_info($coachId);
5231
                $list[] = api_get_person_name(
5232
                    $userInfo['firstname'],
5233
                    $userInfo['lastname']
5234
                );
5235
            }
5236
        }
5237
5238
        return array_to_string($list, CourseManager::USER_SEPARATOR);
5239
    }
5240
5241
    /**
5242
     * Get all coaches added in the session - course relationship
5243
     * @param int $sessionId
5244
     * @return array
5245
     */
5246
    public static function getCoachesBySession($sessionId)
5247
    {
5248
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5249
        $sessionId = intval($sessionId);
5250
5251
        $sql = "SELECT DISTINCT user_id
5252
                FROM $table
5253
                WHERE session_id = '$sessionId' AND status = 2";
5254
        $result = Database::query($sql);
5255
5256
        $coaches = array();
5257
        if (Database::num_rows($result) > 0) {
5258
            while ($row = Database::fetch_array($result)) {
5259
                $coaches[] = $row['user_id'];
5260
            }
5261
        }
5262
5263
        return $coaches;
5264
    }
5265
5266
    /**
5267
     * @param int $userId
5268
     * @return array
5269
     */
5270
    public static function getAllCoursesFromAllSessionFromDrh($userId)
5271
    {
5272
        $sessions = self::get_sessions_followed_by_drh($userId);
5273
        $coursesFromSession = array();
5274
        if (!empty($sessions)) {
5275
            foreach ($sessions as $session) {
5276
                $courseList = self::get_course_list_by_session_id($session['id']);
5277
                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...
5278
                    $coursesFromSession[] = $course['code'];
5279
                }
5280
            }
5281
        }
5282
        return $coursesFromSession;
5283
    }
5284
5285
    /**
5286
     * getAllCoursesFromAllSessions
5287
     *
5288
     * @return array
5289
     */
5290
    public static function getAllCoursesFromAllSessions()
5291
    {
5292
        $sessions = self::get_sessions_list();
5293
        $coursesFromSession = array();
5294
        if (!empty($sessions)) {
5295
            foreach ($sessions as $session) {
5296
                $courseList = self::get_course_list_by_session_id($session['id']);
5297
                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...
5298
                    $coursesFromSession[$course['code'].':'.$session['id']] = $course['visual_code'] . ' - ' . $course['title'] . ' (' . $session['name'] . ')';
5299
                }
5300
            }
5301
        }
5302
        return $coursesFromSession;
5303
    }
5304
5305
    /**
5306
     * @param string $status
5307
     * @param int $userId
5308
     * @param bool $getCount
5309
     * @param int  $from
5310
     * @param int  $numberItems
5311
     * @param int $column
5312
     * @param string $direction
5313
     * @param string $keyword
5314
     * @param string $active
5315
     * @param string $lastConnectionDate
5316
     * @param array $sessionIdList
5317
     * @param array $studentIdList
5318
     * @param int $filterByStatus
5319
     * @return array|int
5320
     */
5321
    public static function getAllUsersFromCoursesFromAllSessionFromStatus(
5322
        $status,
5323
        $userId,
5324
        $getCount = false,
5325
        $from = null,
5326
        $numberItems = null,
5327
        $column = 1,
5328
        $direction = 'asc',
5329
        $keyword = null,
5330
        $active = null,
5331
        $lastConnectionDate = null,
5332
        $sessionIdList = array(),
5333
        $studentIdList = array(),
5334
        $filterByStatus = null
5335
    ) {
5336
        $filterByStatus = intval($filterByStatus);
5337
5338
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
5339
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
5340
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
5341
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5342
        $tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
5343
        $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
5344
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5345
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
5346
5347
        $direction = in_array(strtolower($direction), array('asc', 'desc')) ? $direction : 'asc';
5348
        $column = Database::escape_string($column);
5349
        $userId = intval($userId);
5350
5351
        $limitCondition = null;
5352
5353 View Code Duplication
        if (isset($from) && isset($numberItems)) {
5354
            $from = intval($from);
5355
            $numberItems = intval($numberItems);
5356
            $limitCondition = "LIMIT $from, $numberItems";
5357
        }
5358
5359
        $urlId = api_get_current_access_url_id();
5360
5361
        $sessionConditions = '';
5362
        $courseConditions = '';
5363
        $userConditions = '';
5364
5365
        if (isset($active)) {
5366
            $active = intval($active);
5367
            $userConditions .= " AND active = $active";
5368
        }
5369
5370
        $courseList = CourseManager::get_courses_followed_by_drh($userId, DRH);
5371
        if (!empty($courseList)) {
5372
            $courseIdList = array_column($courseList, 'id');
5373
            $courseConditions = ' AND c.id IN ("'.implode('","', $courseIdList).'")';
5374
        }
5375
5376
        $userConditionsFromDrh = '';
5377
5378
        // Classic DRH
5379
        if (empty($studentIdList)) {
5380
            $studentListSql = UserManager::get_users_followed_by_drh(
5381
                $userId,
5382
                $filterByStatus,
5383
                true,
5384
                false
5385
            );
5386
            if (!empty($studentListSql)) {
5387
                $studentIdList = array_keys($studentListSql);
5388
                $studentListSql = "'".implode("','", $studentIdList)."'";
5389
            }
5390
5391
        } else {
5392
            $studentIdList = array_map('intval', $studentIdList);
5393
            $studentListSql = "'".implode("','", $studentIdList)."'";
5394
        }
5395
        if (!empty($studentListSql)) {
5396
            $userConditionsFromDrh = " AND u.user_id IN (".$studentListSql.") ";
5397
        }
5398
5399
        switch ($status) {
5400
            case 'drh':
5401
                break;
5402
            case 'drh_all':
5403
                // Show all by DRH
5404
                if (empty($sessionIdList)) {
5405
                    $sessionsListSql = self::get_sessions_followed_by_drh(
5406
                        $userId,
5407
                        null,
5408
                        null,
5409
                        false,
5410
                        true,
5411
                        true
5412
                    );
5413
                } else {
5414
                    $sessionIdList = array_map('intval', $sessionIdList);
5415
                    $sessionsListSql = "'".implode("','", $sessionIdList)."'";
5416
                }
5417
                if (!empty($sessionsListSql)) {
5418
                    $sessionConditions = " AND s.id IN (".$sessionsListSql.") ";
5419
                }
5420
                break;
5421
            case 'session_admin':
5422
                $sessionConditions = " AND s.id_coach = $userId ";
5423
                $userConditionsFromDrh = '';
5424
                break;
5425
            case 'admin':
5426
                break;
5427
            case 'teacher':
5428
                $sessionConditions = " AND s.id_coach = $userId ";
5429
                $userConditionsFromDrh = '';
5430
                break;
5431
        }
5432
5433
        $select = "SELECT DISTINCT u.* ";
5434
        $masterSelect = "SELECT DISTINCT * FROM ";
5435
5436
        if ($getCount) {
5437
            $select = "SELECT DISTINCT u.user_id ";
5438
            $masterSelect = "SELECT COUNT(DISTINCT(user_id)) as count FROM ";
5439
        }
5440
5441
        if (!empty($filterByStatus)) {
5442
            $userConditions .= " AND u.status = ".$filterByStatus;
5443
        }
5444
5445
        if (!empty($lastConnectionDate)) {
5446
            $lastConnectionDate = Database::escape_string($lastConnectionDate);
5447
            $userConditions .=  " AND u.last_login <= '$lastConnectionDate' ";
5448
        }
5449
5450 View Code Duplication
        if (!empty($keyword)) {
5451
            $keyword = Database::escape_string($keyword);
5452
            $userConditions .= " AND (
5453
                u.username LIKE '%$keyword%' OR
5454
                u.firstname LIKE '%$keyword%' OR
5455
                u.lastname LIKE '%$keyword%' OR
5456
                u.official_code LIKE '%$keyword%' OR
5457
                u.email LIKE '%$keyword%'
5458
            )";
5459
        }
5460
5461
        $where = " WHERE
5462
                   access_url_id = $urlId
5463
                   $userConditions
5464
        ";
5465
5466
        $userUnion = '';
5467
        if (!empty($userConditionsFromDrh)) {
5468
            $userUnion = "
5469
            UNION (
5470
                $select                    
5471
                FROM $tbl_user u
5472
                INNER JOIN $tbl_user_rel_access_url url ON (url.user_id = u.id)
5473
                $where
5474
                $userConditionsFromDrh
5475
            )";
5476
        }
5477
5478
        $sql = "$masterSelect (
5479
                ($select
5480
                FROM $tbl_session s
5481
                    INNER JOIN $tbl_session_rel_course_rel_user su ON (s.id = su.session_id)
5482
                    INNER JOIN $tbl_user u ON (u.user_id = su.user_id)
5483
                    INNER JOIN $tbl_session_rel_access_url url ON (url.session_id = s.id)
5484
                    $where
5485
                    $sessionConditions
5486
                    $userConditionsFromDrh
5487
                ) UNION (
5488
                    $select
5489
                    FROM $tbl_course c
5490
                    INNER JOIN $tbl_course_user cu ON (cu.c_id = c.id)
5491
                    INNER JOIN $tbl_user u ON (u.user_id = cu.user_id)
5492
                    INNER JOIN $tbl_course_rel_access_url url ON (url.c_id = c.id)
5493
                    $where
5494
                    $courseConditions
5495
                    $userConditionsFromDrh
5496
                ) $userUnion
5497
                ) as t1
5498
                ";
5499
5500 View Code Duplication
        if ($getCount) {
5501
            $result = Database::query($sql);
5502
            $count = 0;
5503
            if (Database::num_rows($result)) {
5504
                $rows = Database::fetch_array($result);
5505
                $count = $rows['count'];
5506
            }
5507
            return $count;
5508
        }
5509
5510 View Code Duplication
        if (!empty($column) && !empty($direction)) {
5511
            $column = str_replace('u.', '', $column);
5512
            $sql .= " ORDER BY $column $direction ";
5513
        }
5514
5515
        $sql .= $limitCondition;
5516
        $result = Database::query($sql);
5517
        $result = Database::store_result($result);
5518
5519
        return $result ;
5520
    }
5521
5522
    /**
5523
     * @param int $sessionId
5524
     * @param int $courseId
5525
     * @param array $coachList
5526
     * @param bool $deleteCoachesNotInList
5527
     */
5528
    public static function updateCoaches(
5529
        $sessionId,
5530
        $courseId,
5531
        $coachList,
5532
        $deleteCoachesNotInList = false
5533
    ) {
5534
        $currentCoaches = self::getCoachesByCourseSession($sessionId, $courseId);
5535
5536
        if (!empty($coachList)) {
5537
            foreach ($coachList as $userId) {
5538
                self::set_coach_to_course_session($userId, $sessionId, $courseId);
5539
            }
5540
        }
5541
5542
        if ($deleteCoachesNotInList) {
5543
            if (!empty($coachList)) {
5544
                $coachesToDelete = array_diff($currentCoaches, $coachList);
5545
            } else {
5546
                $coachesToDelete = $currentCoaches;
5547
            }
5548
5549
            if (!empty($coachesToDelete)) {
5550
                foreach ($coachesToDelete as $userId) {
5551
                    self::set_coach_to_course_session(
5552
                        $userId,
5553
                        $sessionId,
5554
                        $courseId,
5555
                        true
5556
                    );
5557
                }
5558
            }
5559
        }
5560
    }
5561
5562
    /**
5563
     * @param array $sessions
5564
     * @param array $sessionsDestination
5565
     * @return string
5566
     */
5567
    public static function copyStudentsFromSession($sessions, $sessionsDestination)
5568
    {
5569
        $messages = array();
5570
        if (!empty($sessions)) {
5571
            foreach ($sessions as $sessionId) {
5572
                $sessionInfo = self::fetch($sessionId);
5573
                $userList = self::get_users_by_session($sessionId, 0);
5574
                if (!empty($userList)) {
5575
                    $newUserList = array();
5576
                    $userToString = null;
5577
                    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...
5578
                        $newUserList[] = $userInfo['user_id'];
5579
                        $userToString .= $userInfo['firstname'] . ' ' . $userInfo['lastname'] . '<br />';
5580
                    }
5581
5582
                    if (!empty($sessionsDestination)) {
5583
                        foreach ($sessionsDestination as $sessionDestinationId) {
5584
                            $sessionDestinationInfo = self::fetch($sessionDestinationId);
5585
                            $messages[] = Display::return_message(
5586
                                sprintf(get_lang('AddingStudentsFromSessionXToSessionY'), $sessionInfo['name'], $sessionDestinationInfo['name']), 'info', false
5587
                            );
5588
                            if ($sessionId == $sessionDestinationId) {
5589
                                $messages[] = Display::return_message(sprintf(get_lang('SessionXSkipped'), $sessionDestinationId), 'warning', false);
5590
                                continue;
5591
                            }
5592
                            $messages[] = Display::return_message(get_lang('StudentList') . '<br />' . $userToString, 'info', false);
5593
                            self::subscribe_users_to_session(
5594
                                $sessionDestinationId,
5595
                                $newUserList,
5596
                                SESSION_VISIBLE_READ_ONLY,
5597
                                false
5598
                            );
5599
                        }
5600
                    } else {
5601
                        $messages[] = Display::return_message(get_lang('NoDestinationSessionProvided'), 'warning');
5602
                    }
5603
                } else {
5604
                    $messages[] = Display::return_message(
5605
                        get_lang('NoStudentsFoundForSession').' #'.$sessionInfo['name'],
5606
                        'warning'
5607
                    );
5608
                }
5609
            }
5610
        } else {
5611
            $messages[] = Display::return_message(get_lang('NoData'), 'warning');
5612
        }
5613
        return $messages;
5614
    }
5615
5616
    /**
5617
     * Assign coaches of a session(s) as teachers to a given course (or courses)
5618
     * @param array A list of session IDs
5619
     * @param array A list of course IDs
5620
     * @return string
5621
     */
5622
    public static function copyCoachesFromSessionToCourse($sessions, $courses)
5623
    {
5624
        $coachesPerSession = array();
5625
        foreach ($sessions as $sessionId) {
5626
            $coaches = self::getCoachesBySession($sessionId);
5627
            $coachesPerSession[$sessionId] = $coaches;
5628
        }
5629
5630
        $result = array();
5631
5632
        if (!empty($courses)) {
5633
            foreach ($courses as $courseId) {
5634
                $courseInfo = api_get_course_info_by_id($courseId);
5635
                foreach ($coachesPerSession as $sessionId => $coachList) {
5636
                    CourseManager::updateTeachers(
5637
                        $courseInfo,
5638
                        $coachList,
5639
                        false,
5640
                        false,
5641
                        false
5642
                    );
5643
                    $result[$courseInfo['code']][$sessionId] = $coachList;
5644
                }
5645
            }
5646
        }
5647
        $sessionUrl = api_get_path(WEB_CODE_PATH) . 'session/resume_session.php?id_session=';
5648
        $htmlResult = null;
5649
5650
        if (!empty($result)) {
5651
            foreach ($result as $courseCode => $data) {
5652
                $url = api_get_course_url($courseCode);
5653
                $htmlResult .= sprintf(
5654
                    get_lang('CoachesSubscribedAsATeacherInCourseX'),
5655
                    Display::url($courseCode, $url, array('target' => '_blank'))
5656
                );
5657
                foreach ($data as $sessionId => $coachList) {
5658
                    $sessionInfo = self::fetch($sessionId);
5659
                    $htmlResult .= '<br />';
5660
                    $htmlResult .= Display::url(
5661
                        get_lang('Session') . ': ' . $sessionInfo['name'] . ' <br />', $sessionUrl . $sessionId, array('target' => '_blank')
5662
                    );
5663
                    $teacherList = array();
5664
                    foreach ($coachList as $coachId) {
5665
                        $userInfo = api_get_user_info($coachId);
5666
                        $teacherList[] = $userInfo['complete_name'];
5667
                    }
5668
                    if (!empty($teacherList)) {
5669
                        $htmlResult .= implode(', ', $teacherList);
5670
                    } else {
5671
                        $htmlResult .= get_lang('NothingToAdd');
5672
                    }
5673
                }
5674
                $htmlResult .= '<br />';
5675
            }
5676
            $htmlResult = Display::return_message($htmlResult, 'normal', false);
5677
        }
5678
        return $htmlResult;
5679
    }
5680
5681
    /**
5682
     * @param string $keyword
5683
     * @param string $active
5684
     * @param string $lastConnectionDate
5685
     * @param array $sessionIdList
5686
     * @param array $studentIdList
5687
     * @param int $filterUserStatus STUDENT|COURSEMANAGER constants
5688
     *
5689
     * @return array|int
5690
     */
5691
    public static function getCountUserTracking(
5692
        $keyword = null,
5693
        $active = null,
5694
        $lastConnectionDate = null,
5695
        $sessionIdList = array(),
5696
        $studentIdList = array(),
5697
        $filterUserStatus = null
5698
    ) {
5699
        $userId = api_get_user_id();
5700
        $drhLoaded = false;
5701
5702
        if (api_is_drh()) {
5703
            if (api_drh_can_access_all_session_content()) {
5704
                $count = self::getAllUsersFromCoursesFromAllSessionFromStatus(
5705
                    'drh_all',
5706
                    $userId,
5707
                    true,
5708
                    null,
5709
                    null,
5710
                    null,
5711
                    null,
5712
                    $keyword,
5713
                    $active,
5714
                    $lastConnectionDate,
5715
                    $sessionIdList,
5716
                    $studentIdList,
5717
                    $filterUserStatus
5718
                );
5719
                $drhLoaded = true;
5720
            }
5721
        }
5722
5723
        if ($drhLoaded == false) {
5724
            $count = UserManager::getUsersFollowedByUser(
5725
                $userId,
5726
                $filterUserStatus,
5727
                false,
5728
                false,
5729
                true,
5730
                null,
5731
                null,
5732
                null,
5733
                null,
5734
                $active,
5735
                $lastConnectionDate,
5736
                api_is_student_boss() ? STUDENT_BOSS : COURSEMANAGER,
5737
                $keyword
5738
            );
5739
        }
5740
5741
        return $count;
5742
    }
5743
5744
    /**
5745
     * Get teachers followed by a user
5746
     * @param int $userId
5747
     * @param int $active
5748
     * @param string $lastConnectionDate
5749
     * @param bool $getCount
5750
     * @param array $sessionIdList
5751
     * @return array|int
5752
     */
5753
    public static function getTeacherTracking(
5754
        $userId,
5755
        $active = 1,
5756
        $lastConnectionDate = null,
5757
        $getCount = false,
5758
        $sessionIdList = array()
5759
    ) {
5760
        $teacherListId = array();
5761
5762
        if (api_is_drh() || api_is_platform_admin()) {
5763
            // Followed teachers by drh
5764
            if (api_drh_can_access_all_session_content()) {
5765
                if (empty($sessionIdList)) {
5766
                    $sessions = self::get_sessions_followed_by_drh($userId);
5767
                    $sessionIdList = array();
5768
                    foreach ($sessions as $session) {
5769
                        $sessionIdList[] = $session['id'];
5770
                    }
5771
                }
5772
5773
                $sessionIdList = array_map('intval', $sessionIdList);
5774
                $sessionToString = implode("', '",  $sessionIdList);
5775
5776
                $course = Database::get_main_table(TABLE_MAIN_COURSE);
5777
                $sessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
5778
                $courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5779
5780
                // Select the teachers.
5781
                $sql = "SELECT DISTINCT(cu.user_id) FROM $course c
5782
                        INNER JOIN $sessionCourse src ON c.id = src.c_id
5783
                        INNER JOIN $courseUser cu ON (cu.c_id = c.id)
5784
		                WHERE src.session_id IN ('$sessionToString') AND cu.status = 1";
5785
                $result = Database::query($sql);
5786
                while($row = Database::fetch_array($result, 'ASSOC')) {
5787
                    $teacherListId[$row['user_id']] = $row['user_id'];
5788
                }
5789
            } else {
5790
                $teacherResult = UserManager::get_users_followed_by_drh($userId, COURSEMANAGER);
5791
                foreach ($teacherResult as $userInfo) {
5792
                    $teacherListId[] = $userInfo['user_id'];
5793
                }
5794
            }
5795
        }
5796
5797
        if (!empty($teacherListId)) {
5798
            $tableUser = Database::get_main_table(TABLE_MAIN_USER);
5799
5800
            $select = "SELECT DISTINCT u.* ";
5801
            if ($getCount) {
5802
                $select = "SELECT count(DISTINCT(u.user_id)) as count";
5803
            }
5804
5805
            $sql = "$select FROM $tableUser u";
5806
5807
            if (!empty($lastConnectionDate)) {
5808
                $tableLogin = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
5809
                //$sql .= " INNER JOIN $tableLogin l ON (l.login_user_id = u.user_id) ";
5810
            }
5811
            $active = intval($active);
5812
            $teacherListId = implode("','", $teacherListId);
5813
            $where = " WHERE u.active = $active AND u.user_id IN ('$teacherListId') ";
5814
5815
            if (!empty($lastConnectionDate)) {
5816
                $lastConnectionDate = Database::escape_string($lastConnectionDate);
5817
                //$where .= " AND l.login_date <= '$lastConnectionDate' ";
5818
            }
5819
5820
            $sql .= $where;
5821
            $result = Database::query($sql);
5822
            if (Database::num_rows($result)) {
5823
                if ($getCount) {
5824
                    $row = Database::fetch_array($result);
5825
                    return $row['count'];
5826
                } else {
5827
5828
                    return Database::store_result($result, 'ASSOC');
5829
                }
5830
            }
5831
        }
5832
5833
        return 0;
5834
    }
5835
5836
    /**
5837
     * Get the list of course tools that have to be dealt with in case of
5838
     * registering any course to a session
5839
     * @return array The list of tools to be dealt with (literal names)
5840
     */
5841
    public static function getCourseToolToBeManaged()
5842
    {
5843
        return array(
5844
            'courseDescription',
5845
            'courseIntroduction',
5846
        );
5847
    }
5848
5849
    /**
5850
     * Calls the methods bound to each tool when a course is registered into a session
5851
     * @param int $sessionId
5852
     * @param int $courseId
5853
     * @return void
5854
     */
5855 View Code Duplication
    public static function installCourse($sessionId, $courseId)
5856
    {
5857
        return true;
5858
        $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...
5859
5860
        foreach ($toolList as $tool) {
5861
            $method = 'add' . $tool;
5862
            if (method_exists(get_class(), $method)) {
5863
                self::$method($sessionId, $courseId);
5864
            }
5865
        }
5866
    }
5867
5868
    /**
5869
     * Calls the methods bound to each tool when a course is unregistered from
5870
     * a session
5871
     * @param int $sessionId
5872
     * @param int $courseId
5873
     */
5874 View Code Duplication
    public static function unInstallCourse($sessionId, $courseId)
5875
    {
5876
        return true;
5877
        $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...
5878
5879
        foreach ($toolList as $tool) {
5880
            $method = 'remove' . $tool;
5881
            if (method_exists(get_class(), $method)) {
5882
                self::$method($sessionId, $courseId);
5883
            }
5884
        }
5885
    }
5886
5887
    /**
5888
     * @param int $sessionId
5889
     * @param int $courseId
5890
     */
5891
    public static function addCourseIntroduction($sessionId, $courseId)
5892
    {
5893
        // @todo create a tool intro lib
5894
        $sessionId = intval($sessionId);
5895
        $courseId = intval($courseId);
5896
5897
        $TBL_INTRODUCTION = Database::get_course_table(TABLE_TOOL_INTRO);
5898
        $sql = "SELECT * FROM $TBL_INTRODUCTION WHERE c_id = $courseId";
5899
        $result = Database::query($sql);
5900
        $result = Database::store_result($result, 'ASSOC');
5901
5902
        if (!empty($result)) {
5903
            foreach ($result as $result) {
5904
                // @todo check if relation exits.
5905
                $result['session_id'] = $sessionId;
5906
                Database::insert($TBL_INTRODUCTION, $result);
5907
            }
5908
        }
5909
    }
5910
5911
    /**
5912
     * @param int $sessionId
5913
     * @param int $courseId
5914
     */
5915 View Code Duplication
    public static function removeCourseIntroduction($sessionId, $courseId)
5916
    {
5917
        $sessionId = intval($sessionId);
5918
        $courseId = intval($courseId);
5919
        $TBL_INTRODUCTION = Database::get_course_table(TABLE_TOOL_INTRO);
5920
        $sql = "DELETE FROM $TBL_INTRODUCTION
5921
                WHERE c_id = $courseId AND session_id = $sessionId";
5922
        Database::query($sql);
5923
    }
5924
5925
    /**
5926
     * @param int $sessionId
5927
     * @param int $courseId
5928
     */
5929
    public static function addCourseDescription($sessionId, $courseId)
5930
    {
5931
        /* $description = new CourseDescription();
5932
          $descriptions = $description->get_descriptions($courseId);
5933
          foreach ($descriptions as $description) {
5934
          } */
5935
    }
5936
5937
    /**
5938
     * @param int $sessionId
5939
     * @param int $courseId
5940
     */
5941
    public static function removeCourseDescription($sessionId, $courseId)
5942
    {
5943
5944
    }
5945
5946
    /**
5947
     * @param array $userSessionList format see self::importSessionDrhCSV()
5948
     * @param bool $sendEmail
5949
     * @param bool $removeOldRelationShips
5950
     * @return string
5951
     */
5952
    public static function subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips)
5953
    {
5954
        if (!empty($userSessionList)) {
5955
            foreach ($userSessionList as $userId => $data) {
5956
                $sessionList = array();
5957
                foreach ($data['session_list'] as $sessionInfo) {
5958
                    $sessionList[] = $sessionInfo['session_id'];
5959
                }
5960
                $userInfo = $data['user_info'];
5961
                self::subscribeSessionsToDrh(
5962
                    $userInfo,
5963
                    $sessionList,
5964
                    $sendEmail,
5965
                    $removeOldRelationShips
5966
                );
5967
            }
5968
        }
5969
    }
5970
5971
    /**
5972
     * @param array $userSessionList format see self::importSessionDrhCSV()
5973
     *
5974
     * @return string
5975
     */
5976
    public static function checkSubscribeDrhToSessionList($userSessionList)
5977
    {
5978
        $message = null;
5979
        if (!empty($userSessionList)) {
5980
            if (!empty($userSessionList)) {
5981
                foreach ($userSessionList as $userId => $data) {
5982
                    $userInfo = $data['user_info'];
5983
5984
                    $sessionListSubscribed = self::get_sessions_followed_by_drh($userId);
5985
                    if (!empty($sessionListSubscribed)) {
5986
                        $sessionListSubscribed = array_keys($sessionListSubscribed);
5987
                    }
5988
5989
                    $sessionList = array();
5990
                    if (!empty($data['session_list'])) {
5991
                        foreach ($data['session_list'] as $sessionInfo) {
5992
                            if (in_array($sessionInfo['session_id'], $sessionListSubscribed)) {
5993
                                $sessionList[] = $sessionInfo['session_info']['name'];
5994
                            }
5995
                        }
5996
                    }
5997
5998
                    $message .= '<strong>' . get_lang('User') . '</strong> ' . $userInfo['complete_name'] . ' <br />';
5999
6000
                    if (!in_array($userInfo['status'], array(DRH)) && !api_is_platform_admin_by_id($userInfo['user_id'])) {
6001
                        $message .= get_lang('UserMustHaveTheDrhRole') . '<br />';
6002
                        continue;
6003
                    }
6004
6005
                    if (!empty($sessionList)) {
6006
                        $message .= '<strong>' . get_lang('Sessions') . ':</strong> <br />';
6007
                        $message .= implode(', ', $sessionList) . '<br /><br />';
6008
                    } else {
6009
                        $message .= get_lang('NoSessionProvided') . ' <br /><br />';
6010
                    }
6011
                }
6012
            }
6013
        }
6014
6015
        return $message;
6016
    }
6017
6018
    /**
6019
     * @param string $file
6020
     * @param bool $sendEmail
6021
     * @param bool $removeOldRelationShips
6022
     *
6023
     * @return string
6024
     */
6025
    public static function importSessionDrhCSV($file, $sendEmail, $removeOldRelationShips)
6026
    {
6027
        $list = Import::csv_reader($file);
6028
6029
        if (!empty($list)) {
6030
            $userSessionList = array();
6031
            foreach ($list as $data) {
6032
                $userInfo = api_get_user_info_from_username($data['Username']);
6033
                $sessionInfo = self::get_session_by_name($data['SessionName']);
6034
6035
                if (!empty($userInfo) && !empty($sessionInfo)) {
6036
                    $userSessionList[$userInfo['user_id']]['session_list'][] = array(
6037
                        'session_id' => $sessionInfo['id'],
6038
                        'session_info' => $sessionInfo,
6039
                    );
6040
                    $userSessionList[$userInfo['user_id']]['user_info'] = $userInfo;
6041
                }
6042
            }
6043
6044
            self::subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips);
6045
            return self::checkSubscribeDrhToSessionList($userSessionList);
6046
        }
6047
    }
6048
6049
    /**
6050
     * Courses re-ordering in resume_session.php flag see BT#8316
6051
     */
6052
    public static function orderCourseIsEnabled()
6053
    {
6054
        $sessionCourseOrder = api_get_setting('session_course_ordering');
6055
        if ($sessionCourseOrder === 'true') {
6056
            return true;
6057
        }
6058
6059
        return false;
6060
    }
6061
6062
    /**
6063
     * @param string $direction (up/down)
6064
     * @param int $sessionId
6065
     * @param int $courseId
6066
     * @return bool
6067
     */
6068
    public static function move($direction, $sessionId, $courseId)
6069
    {
6070
        if (!self::orderCourseIsEnabled()) {
6071
            return false;
6072
        }
6073
6074
        $sessionId = intval($sessionId);
6075
        $courseId = intval($courseId);
6076
6077
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6078
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
6079
6080
        $position = array();
6081
        $count = 0;
6082
        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...
6083
            if ($course['position'] == '') {
6084
                $course['position'] = $count;
6085
            }
6086
            $position[$course['code']] = $course['position'];
6087
            // Saving current order.
6088
            $sql = "UPDATE $table SET position = $count
6089
                    WHERE session_id = $sessionId AND c_id = '".$course['real_id']."'";
6090
            Database::query($sql);
6091
            $count++;
6092
        }
6093
6094
        // Loading new positions.
6095
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
6096
6097
        $found = false;
6098
6099
        switch ($direction) {
6100
            case 'up':
6101
                $courseList = array_reverse($courseList);
6102
                break;
6103
            case 'down':
6104
                break;
6105
        }
6106
6107
        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...
6108
            if ($found) {
6109
                $nextId = $course['real_id'];
6110
                $nextOrder = $course['position'];
6111
                break;
6112
            }
6113
6114
            if ($courseId == $course['real_id']) {
6115
                $thisCourseCode = $course['real_id'];
6116
                $thisOrder = $course['position'];
6117
                $found = true;
6118
            }
6119
        }
6120
6121
        $sql1 = "UPDATE $table SET position = '".intval($nextOrder)."'
6122
                 WHERE session_id = $sessionId AND c_id =  $thisCourseCode";
6123
        Database::query($sql1);
6124
6125
        $sql2 = "UPDATE $table SET position = '".intval($thisOrder)."'
6126
                 WHERE session_id = $sessionId AND c_id = $nextId";
6127
        Database::query($sql2);
6128
6129
        return true;
6130
    }
6131
6132
    /**
6133
     * @param int $sessionId
6134
     * @param int $courseId
6135
     * @return bool
6136
     */
6137
    public static function moveUp($sessionId, $courseId)
6138
    {
6139
        return self::move('up', $sessionId, $courseId);
6140
    }
6141
6142
    /**
6143
     * @param int $sessionId
6144
     * @param string $courseCode
6145
     * @return bool
6146
     */
6147
    public static function moveDown($sessionId, $courseCode)
6148
    {
6149
        return self::move('down', $sessionId, $courseCode);
6150
    }
6151
6152
    /**
6153
     * Use the session duration to allow/block user access see BT#8317
6154
     * Needs these DB changes
6155
     * ALTER TABLE session ADD COLUMN duration int;
6156
     * ALTER TABLE session_rel_user ADD COLUMN duration int;
6157
     */
6158
    public static function durationPerUserIsEnabled()
6159
    {
6160
        return api_get_configuration_value('session_duration_feature');
6161
    }
6162
6163
    /**
6164
     * Returns the number of days the student has left in a session when using
6165
     * sessions durations
6166
     * @param int $userId
6167
     * @param int $sessionId
0 ignored issues
show
Bug introduced by
There is no parameter named $sessionId. Was it maybe removed?

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

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

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

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

Loading history...
6168
     * @param int $duration in days
0 ignored issues
show
Bug introduced by
There is no parameter named $duration. Was it maybe removed?

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

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

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

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

Loading history...
6169
     * @return int
6170
     */
6171
    public static function getDayLeftInSession(array $sessionInfo, $userId)
6172
    {
6173
        $sessionId = $sessionInfo['id'];
6174
        $userSubsubscription = SessionManager::getUserSession($userId, $sessionId);
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
6175
        $duration = empty($userSubsubscription['duration'])
6176
            ? $sessionInfo['duration']
6177
            : $sessionInfo['duration'] + $userSubsubscription['duration'];
6178
6179
        // Get an array with the details of the first access of the student to
6180
        // this session
6181
        $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
6182
            $sessionId,
6183
            $userId
6184
        );
6185
6186
        $currentTime = time();
6187
6188
        // If no previous access, return false
6189
        if (count($courseAccess) == 0) {
6190
            return $duration;
6191
        }
6192
6193
        $firstAccess = api_strtotime($courseAccess['login_course_date'], 'UTC');
6194
6195
        $endDateInSeconds = $firstAccess + $duration*24*60*60;
6196
        $leftDays = round(($endDateInSeconds- $currentTime) / 60 / 60 / 24);
6197
6198
        return $leftDays;
6199
    }
6200
6201
    /**
6202
     * @param int $duration
6203
     * @param int $userId
6204
     * @param int $sessionId
6205
     */
6206
    public static function editUserSessionDuration($duration, $userId, $sessionId)
6207
    {
6208
        $duration = intval($duration);
6209
        $userId = intval($userId);
6210
        $sessionId = intval($sessionId);
6211
6212
        if (empty($userId) || empty($sessionId)) {
6213
            return false;
6214
        }
6215
6216
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6217
        $parameters = array('duration' => $duration);
6218
        $where = array('session_id = ? AND user_id = ? ' => array($sessionId, $userId));
6219
        Database::update($table, $parameters, $where);
6220
    }
6221
6222
    /**
6223
     * Gets one row from the session_rel_user table
6224
     * @param int $userId
6225
     * @param int $sessionId
6226
     *
6227
     * @return array
6228
     */
6229
    public static function getUserSession($userId, $sessionId)
6230
    {
6231
        $userId = intval($userId);
6232
        $sessionId = intval($sessionId);
6233
6234
        if (empty($userId) || empty($sessionId)) {
6235
            return false;
6236
        }
6237
6238
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6239
        $sql = "SELECT * FROM $table
6240
                WHERE session_id = $sessionId AND user_id = $userId";
6241
        $result = Database::query($sql);
6242
        $values = array();
6243
        if (Database::num_rows($result)) {
6244
            $values = Database::fetch_array($result, 'ASSOC');
6245
        }
6246
6247
        return $values;
6248
    }
6249
6250
    /**
6251
     * Check if user is subscribed inside a session as student
6252
     * @param int $sessionId The session id
6253
     * @param int $userId The user id
6254
     * @return boolean Whether is subscribed
6255
     */
6256
    public static function isUserSubscribedAsStudent($sessionId, $userId)
6257
    {
6258
        $sessionRelUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6259
6260
        $sessionId = intval($sessionId);
6261
        $userId = intval($userId);
6262
6263
        // COUNT(1) actually returns the number of rows from the table (as if
6264
        // counting the results from the first column)
6265
        $sql = "SELECT COUNT(1) AS qty FROM $sessionRelUserTable
6266
                WHERE
6267
                    session_id = $sessionId AND
6268
                    user_id = $userId AND
6269
                    relation_type = 0";
6270
6271
        $result = Database::fetch_assoc(Database::query($sql));
6272
6273
        if (!empty($result) && $result['qty'] > 0) {
6274
            return true;
6275
        }
6276
6277
        return false;
6278
    }
6279
6280
    /**
6281
     * Get the session coached by a user (general coach and course-session coach)
6282
     * @param int $coachId The coach id
6283
     * @param boolean $checkSessionRelUserVisibility Check the session visibility
6284
     * @param boolean $asPlatformAdmin The user is a platform admin and we want all sessions
6285
     * @return array The session list
6286
     */
6287
    public static function getSessionsCoachedByUser($coachId, $checkSessionRelUserVisibility = false, $asPlatformAdmin = false)
6288
    {
6289
        // Get all sessions where $coachId is the general coach
6290
        $sessions = self::get_sessions_by_general_coach($coachId, $asPlatformAdmin);
6291
        // Get all sessions where $coachId is the course - session coach
6292
        $courseSessionList = self::getCoursesListByCourseCoach($coachId);
6293
        $sessionsByCoach = array();
6294
        if (!empty($courseSessionList)) {
6295
            foreach ($courseSessionList as $userCourseSubscription) {
6296
                $session = $userCourseSubscription->getSession();
6297
                $sessionsByCoach[$session->getId()] = api_get_session_info(
6298
                    $session->getId()
6299
                );
6300
            }
6301
        }
6302
6303
        if (!empty($sessionsByCoach)) {
6304
            $sessions = array_merge($sessions, $sessionsByCoach);
6305
        }
6306
6307
        // Remove repeated sessions
6308
        if (!empty($sessions)) {
6309
            $cleanSessions = array();
6310
            foreach ($sessions as $session) {
6311
                $cleanSessions[$session['id']] = $session;
6312
            }
6313
            $sessions = $cleanSessions;
6314
        }
6315
6316
        if ($checkSessionRelUserVisibility) {
6317
            if (!empty($sessions)) {
6318
                $newSessions = array();
6319
                foreach ($sessions as $session) {
6320
                    $visibility = api_get_session_visibility($session['id']);
6321
                    if ($visibility == SESSION_INVISIBLE) {
6322
                        continue;
6323
                    }
6324
                    $newSessions[] = $session;
6325
                }
6326
                $sessions = $newSessions;
6327
            }
6328
        }
6329
6330
        return $sessions;
6331
    }
6332
6333
    /**
6334
     * Check if the course belongs to the session
6335
     * @param int $sessionId The session id
6336
     * @param string $courseCode The course code
6337
     *
6338
     * @return bool
6339
     */
6340
    public static function sessionHasCourse($sessionId, $courseCode)
6341
    {
6342
        $sessionId = intval($sessionId);
6343
        $courseCode = Database::escape_string($courseCode);
6344
6345
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
6346
        $sessionRelCourseTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6347
6348
        $sql = "SELECT COUNT(1) AS qty
6349
                FROM $courseTable c
6350
                INNER JOIN $sessionRelCourseTable src
6351
                ON c.id = src.c_id
6352
                WHERE src.session_id = $sessionId
6353
                AND c.code = '$courseCode'  ";
6354
6355
        $result = Database::query($sql);
6356
6357
        if ($result !== false) {
6358
            $data = Database::fetch_assoc($result);
6359
6360
            if ($data['qty'] > 0) {
6361
                return true;
6362
            }
6363
        }
6364
6365
        return false;
6366
    }
6367
6368
    /**
6369
     * Get the list of course coaches
6370
     * @return array The list
6371
     */
6372
    public static function getAllCourseCoaches()
6373
    {
6374
        $coaches = array();
6375
6376
        $scuTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6377
        $userTable = Database::get_main_table(TABLE_MAIN_USER);
6378
6379
        $idResult = Database::select('DISTINCT user_id', $scuTable, array(
6380
            'where' => array(
6381
                'status = ?' => 2,
6382
            ),
6383
        ));
6384
6385
        if ($idResult != false) {
6386
            foreach ($idResult as $idData) {
6387
                $userResult = Database::select('user_id, lastname, firstname, username', $userTable, array(
6388
                    'where' => array(
6389
                        'user_id = ?' => $idData['user_id'],
6390
                    ),
6391
                ), 'first');
6392
6393
                if ($userResult != false) {
6394
                    $coaches[] = array(
6395
                        'id' => $userResult['user_id'],
6396
                        'lastname' => $userResult['lastname'],
6397
                        'firstname' => $userResult['firstname'],
6398
                        'username' => $userResult['username'],
6399
                        'completeName' => api_get_person_name(
6400
                            $userResult['firstname'],
6401
                            $userResult['lastname']
6402
                        ),
6403
                    );
6404
                }
6405
            }
6406
        }
6407
6408
        return $coaches;
6409
    }
6410
6411
    /**
6412
     * Calculate the total user time in the platform
6413
     * @param int $userId The user id
6414
     * @param string $from Optional. From date
6415
     * @param string $until Optional. Until date
6416
     * @return string The time (hh:mm:ss)
6417
     */
6418
    public static function getTotalUserTimeInPlatform($userId, $from = '', $until = '')
6419
    {
6420
        $userId = intval($userId);
6421
6422
        $trackLoginTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
6423
6424
        $whereConditions = array(
6425
            'login_user_id = ? ' => $userId,
6426
        );
6427
6428 View Code Duplication
        if (!empty($from) && !empty($until)) {
6429
            $whereConditions["AND (login_date >= '?' "] = $from;
6430
            $whereConditions["AND logout_date <= DATE_ADD('?', INTERVAL 1 DAY)) "] = $until;
6431
        }
6432
6433
        $trackResult = Database::select(
6434
            'SEC_TO_TIME(SUM(UNIX_TIMESTAMP(logout_date) - UNIX_TIMESTAMP(login_date))) as total_time',
6435
            $trackLoginTable,
6436
            array(
6437
                'where' => $whereConditions,
6438
            ), 'first'
6439
        );
6440
6441
        if ($trackResult != false) {
6442
            return $trackResult['total_time'] ? $trackResult['total_time'] : '00:00:00';
6443
        }
6444
6445
        return '00:00:00';
6446
    }
6447
6448
    /**
6449
     * Get the courses list by a course coach
6450
     * @param int $coachId The coach id
6451
     * @return array (id, user_id, session_id, c_id, visibility, status, legal_agreement)
6452
     */
6453
    public static function getCoursesListByCourseCoach($coachId)
6454
    {
6455
        $entityManager = Database::getManager();
6456
        $scuRepo = $entityManager->getRepository(
6457
            'ChamiloCoreBundle:SessionRelCourseRelUser'
6458
        );
6459
6460
        return $scuRepo->findBy([
6461
            'user' => $coachId,
6462
            'status' => SessionRelCourseRelUser::STATUS_COURSE_COACH
6463
        ]);
6464
    }
6465
6466
    /**
6467
     * Get the count of user courses in session
6468
     * @param int $sessionId The session id
6469
     * @return array
6470
     */
6471 View Code Duplication
    public static function getTotalUserCoursesInSession($sessionId)
6472
    {
6473
        $tableUser = Database::get_main_table(TABLE_MAIN_USER);
6474
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6475
6476
        if (empty($sessionId)) {
6477
            return [];
6478
        }
6479
6480
        $sql = "SELECT 
6481
                    COUNT(u.id) as count, 
6482
                    u.id, 
6483
                    scu.status status_in_session, 
6484
                    u.status user_status
6485
                FROM $table scu
6486
                INNER JOIN $tableUser u 
6487
                ON scu.user_id = u.id
6488
                WHERE scu.session_id = " . intval($sessionId) ."
6489
                GROUP BY u.id";
6490
6491
        $result = Database::query($sql);
6492
6493
        $list = array();
6494
        while ($data = Database::fetch_assoc($result)) {
6495
            $list[] = $data;
6496
        }
6497
6498
        return $list;
6499
    }
6500
6501
6502
    /**
6503
     * Returns list of a few data from session (name, short description, start
6504
     * date, end date) and the given extra fields if defined based on a
6505
     * session category Id.
6506
     * @param int $categoryId The internal ID of the session category
6507
     * @param string $target Value to search for in the session field values
6508
     * @param array $extraFields A list of fields to be scanned and returned
6509
     * @return mixed
6510
     */
6511
    public static function getShortSessionListAndExtraByCategory(
6512
        $categoryId,
6513
        $target,
6514
        $extraFields = null,
6515
        $publicationDate = null
6516
    ) {
6517
        $categoryId = (int) $categoryId;
6518
        $sessionList = array();
6519
        // Check if categoryId is valid
6520
        if ($categoryId > 0) {
6521
            $target = Database::escape_string($target);
6522
            $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
6523
            $sfTable = Database::get_main_table(TABLE_EXTRA_FIELD);
6524
            $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
6525
            // Join session field and session field values tables
6526
            $joinTable = $sfTable . ' sf INNER JOIN ' . $sfvTable . ' sfv ON sf.id = sfv.field_id';
6527
            $fieldsArray = array();
6528
            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...
6529
                $fieldsArray[] = Database::escape_string($field);
6530
            }
6531
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
6532
            if (isset ($publicationDate)) {
6533
                $publicationDateString = $publicationDate->format('Y-m-d H:i:s');
6534
                $wherePublication = " AND id NOT IN (
6535
                    SELECT sfv.item_id FROM $joinTable
6536
                    WHERE
6537
                        sf.extra_field_type = $extraFieldType AND
6538
                        ((sf.variable = 'publication_start_date' AND sfv.value > '$publicationDateString' and sfv.value != '') OR
6539
                        (sf.variable = 'publication_end_date' AND sfv.value < '$publicationDateString' and sfv.value != ''))
6540
                )";
6541
            }
6542
            // Get the session list from session category and target
6543
            $sessionList = Database::select(
6544
                'id, name, access_start_date, access_end_date',
6545
                $sTable,
6546
                array(
6547
                    'where' => array(
6548
                        "session_category_id = ? AND id IN (
6549
                            SELECT sfv.item_id FROM $joinTable
6550
                            WHERE
6551
                                sf.extra_field_type = $extraFieldType AND
6552
                                sfv.item_id = session.id AND
6553
                                sf.variable = 'target' AND
6554
                                sfv.value = ?
6555
                        ) $wherePublication" => array($categoryId, $target),
6556
                    ),
6557
                )
6558
            );
6559
            $whereFieldVariables = array();
6560
            $whereFieldIds = array();
6561
            if (
6562
                is_array($fieldsArray) &&
6563
                count($fieldsArray) > 0
6564
            ) {
6565
                $whereParams = '?';
6566
                for ($i = 1; $i < count($fieldsArray); $i++) {
6567
                    $whereParams .= ', ?';
6568
                }
6569
                $whereFieldVariables = ' variable IN ( ' . $whereParams .' )';
6570
                $whereFieldIds = 'field_id IN ( ' . $whereParams .  ' )';
6571
            }
6572
            // Get session fields
6573
            $extraField = new ExtraFieldModel('session');
6574
            $questionMarks = substr(str_repeat('?, ', count($fieldsArray)), 0, -2);
6575
            $fieldsList = $extraField->get_all(array(
6576
                ' variable IN ( ' . $questionMarks . ' )' => $fieldsArray,
6577
            ));
6578
            // Index session fields
6579
            foreach ($fieldsList as $field) {
6580
                $fields[$field['id']] = $field['variable'];
6581
            }
6582
            // Get session field values
6583
            $extra = new ExtraFieldValue('session');
6584
            $questionMarksFields = substr(str_repeat('?, ', count($fields)), 0, -2);
6585
            $sessionFieldValueList = $extra->get_all(array ('where' => array('field_id IN ( ' . $questionMarksFields . ' )' => array_keys($fields))));
6586
            // Add session fields values to session list
6587
            foreach ($sessionList as $id => &$session) {
6588
                foreach ($sessionFieldValueList as $sessionFieldValue) {
6589
                    // Match session field values to session
6590
                    if ($sessionFieldValue['item_id'] == $id) {
6591
                        // Check if session field value is set in session field list
6592
                        if (isset($fields[$sessionFieldValue['field_id']])) {
6593
                            // Avoid overwriting the session's ID field
6594
                            if ($fields[$sessionFieldValue['field_id']] != 'id') {
6595
                                $var = $fields[$sessionFieldValue['field_id']];
6596
                                $val = $sessionFieldValue['value'];
6597
                                // Assign session field value to session
6598
                                $session[$var] = $val;
6599
                            }
6600
                        }
6601
                    }
6602
                }
6603
            }
6604
        }
6605
6606
        return $sessionList;
6607
    }
6608
6609
    /**
6610
     * Return the Session Category id searched by name
6611
     * @param string $categoryName Name attribute of session category used for search query
6612
     * @param bool $force boolean used to get even if something is wrong (e.g not unique name)
6613
     * @return int|array If success, return category id (int), else it will return an array
6614
     * with the next structure:
6615
     * array('error' => true, 'errorMessage' => ERROR_MESSAGE)
6616
     */
6617
    public static function getSessionCategoryIdByName($categoryName, $force = false)
6618
    {
6619
        // Start error result
6620
        $errorResult = array('error' => true, 'errorMessage' => get_lang('ThereWasAnError'));
6621
        $categoryName = Database::escape_string($categoryName);
6622
        // Check if is not empty category name
6623
        if (!empty($categoryName)) {
6624
            $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
6625
            // Get all session category with same name
6626
            $result = Database::select(
6627
                'id',
6628
                $sessionCategoryTable,
6629
                array(
6630
                    'where' => array(
6631
                        'name = ?' => $categoryName,
6632
                    ),
6633
                )
6634
            );
6635
            // Check the result
6636
            if ($result < 1) {
6637
                // If not found any result, update error message
6638
                $errorResult['errorMessage'] = 'Not found any session category name ' . $categoryName;
6639
            } elseif (count($result) > 1 && !$force) {
6640
                // If found more than one result and force is disabled, update error message
6641
                $errorResult['errorMessage'] = 'Found many session categories';
6642
            } elseif (count($result) == 1 || $force) {
6643
                // If found just one session category or force option is enabled
6644
6645
                return key($result);
6646
            }
6647
        } else {
6648
            // category name is empty, update error message
6649
            $errorResult['errorMessage'] = 'Not valid category name';
6650
        }
6651
6652
        return $errorResult;
6653
    }
6654
6655
    /**
6656
     * Return all data from sessions (plus extra field, course and coach data) by category id
6657
     * @param int $sessionCategoryId session category id used to search sessions
6658
     * @return array If success, return session list and more session related data, else it will return an array
6659
     * with the next structure:
6660
     * array('error' => true, 'errorMessage' => ERROR_MESSAGE)
6661
     */
6662
    public static function getSessionListAndExtraByCategoryId($sessionCategoryId)
6663
    {
6664
        // Start error result
6665
        $errorResult = array(
6666
            'error' => true,
6667
            'errorMessage' => get_lang('ThereWasAnError'),
6668
        );
6669
6670
        $sessionCategoryId = intval($sessionCategoryId);
6671
        // Check if session category id is valid
6672
        if ($sessionCategoryId > 0) {
6673
            // Get table names
6674
            $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
6675
            $sessionFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
6676
            $sessionFieldValueTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
6677
            $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6678
            $userTable = Database::get_main_table(TABLE_MAIN_USER);
6679
            $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
6680
6681
            // Get all data from all sessions whit the session category specified
6682
            $sessionList = Database::select(
6683
                '*',
6684
                $sessionTable,
6685
                array(
6686
                    'where' => array(
6687
                        'session_category_id = ?' => $sessionCategoryId,
6688
                    ),
6689
                )
6690
            );
6691
6692
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
6693
6694
            // Check if session list query had result
6695
            if (!empty($sessionList)) {
6696
                // implode all session id
6697
                $sessionIdsString = '(' . implode(', ', array_keys($sessionList)) . ')';
6698
                // Get all field variables
6699
                $sessionFieldList = Database::select(
6700
                    'id, variable',
6701
                    $sessionFieldTable,
6702
                    array('extra_field_type = ? ' => array($extraFieldType))
6703
                );
6704
6705
                // Get all field values
6706
                $sql = "SELECT item_id, field_id, value FROM
6707
                        $sessionFieldValueTable v INNER JOIN $sessionFieldTable f
6708
                        ON (f.id = v.field_id)
6709
                        WHERE
6710
                            item_id IN $sessionIdsString AND
6711
                            extra_field_type = $extraFieldType
6712
                ";
6713
                $result = Database::query($sql);
6714
                $sessionFieldValueList = Database::store_result($result, 'ASSOC');
6715
6716
                // Check if session field values had result
6717
                if (!empty($sessionFieldValueList)) {
6718
                    $sessionFieldValueListBySession = array();
6719
                    foreach ($sessionFieldValueList as $key => $sessionFieldValue) {
6720
                        // Create an array to index ids to session id
6721
                        $sessionFieldValueListBySession[$sessionFieldValue['item_id']][] = $key;
6722
                    }
6723
                }
6724
                // Query used to find course-coaches from sessions
6725
                $sql = "SELECT
6726
                            scu.session_id,
6727
                            c.id AS course_id,
6728
                            c.code AS course_code,
6729
                            c.title AS course_title,
6730
                            u.username AS coach_username,
6731
                            u.firstname AS coach_firstname,
6732
                            u.lastname AS coach_lastname
6733
                        FROM $courseTable c
6734
                        INNER JOIN $sessionCourseUserTable scu ON c.id = scu.c_id
6735
                        INNER JOIN $userTable u ON scu.user_id = u.user_id
6736
                        WHERE scu.status = 2 AND scu.session_id IN $sessionIdsString
6737
                        ORDER BY scu.session_id ASC ";
6738
                $res = Database::query($sql);
6739
                $sessionCourseList = Database::store_result($res, 'ASSOC');
6740
                // Check if course list had result
6741
                if (!empty($sessionCourseList)) {
6742
                    foreach ($sessionCourseList as $key => $sessionCourse) {
6743
                        // Create an array to index ids to session_id
6744
                        $sessionCourseListBySession[$sessionCourse['session_id']][] = $key;
6745
                    }
6746
                }
6747
                // Join lists
6748
                if (is_array($sessionList)) {
6749
                    foreach ($sessionList as $id => &$row) {
6750
                        if (
6751
                            !empty($sessionFieldValueListBySession) &&
6752
                            is_array($sessionFieldValueListBySession[$id])
6753
                        ) {
6754
                            // If have an index array for session extra fields, use it to join arrays
6755
                            foreach ($sessionFieldValueListBySession[$id] as $key) {
6756
                                $row['extra'][$key] = array(
6757
                                    'field_name' => $sessionFieldList[$sessionFieldValueList[$key]['field_id']]['variable'],
6758
                                    'value' => $sessionFieldValueList[$key]['value'],
6759
                                );
6760
                            }
6761
                        }
6762
                        if (
6763
                            !empty($sessionCourseListBySession) &&
6764
                            is_array($sessionCourseListBySession[$id])
6765
                        ) {
6766
                            // If have an index array for session course coach, use it to join arrays
6767
                            foreach ($sessionCourseListBySession[$id] as $key) {
6768
                                $row['course'][$key] = array(
6769
                                    'course_id' => $sessionCourseList[$key]['course_id'],
6770
                                    'course_code' => $sessionCourseList[$key]['course_code'],
6771
                                    'course_title' => $sessionCourseList[$key]['course_title'],
6772
                                    'coach_username' => $sessionCourseList[$key]['coach_username'],
6773
                                    'coach_firstname' => $sessionCourseList[$key]['coach_firstname'],
6774
                                    'coach_lastname' => $sessionCourseList[$key]['coach_lastname'],
6775
                                );
6776
                            }
6777
                        }
6778
                    }
6779
                }
6780
6781
                return $sessionList;
6782
            } else {
6783
                // Not found result, update error message
6784
                $errorResult['errorMessage'] = 'Not found any session for session category id ' . $sessionCategoryId;
6785
            }
6786
        }
6787
6788
        return $errorResult;
6789
    }
6790
6791
    /**
6792
     * Return session description from session id
6793
     * @param int $sessionId
6794
     * @return string
6795
     */
6796
    public static function getDescriptionFromSessionId($sessionId)
6797
    {
6798
        // Init variables
6799
        $sessionId = intval($sessionId);
6800
        $description = '';
6801
        // Check if session id is valid
6802
        if ($sessionId > 0) {
6803
            // Select query from session id
6804
            $rows = Database::select(
6805
                'description',
6806
                Database::get_main_table(TABLE_MAIN_SESSION),
6807
                array(
6808
                    'where' => array(
6809
                        'id = ?' => $sessionId,
6810
                    ),
6811
                )
6812
            );
6813
6814
            // Check if select query result is not empty
6815
            if (!empty($rows)) {
6816
                // Get session description
6817
                $description = $rows[0]['description'];
6818
            }
6819
        }
6820
6821
        return $description;
6822
    }
6823
6824
    /**
6825
     * Get a session list filtered by name, description or any of the given extra fields
6826
     * @param string $term The term to search
6827
     * @param array $extraFieldsToInclude Extra fields to include in the session data
6828
     * @return array The list
6829
     */
6830
    public static function searchSession($term, $extraFieldsToInclude = array())
6831
    {
6832
        $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
6833
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
6834
        $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
6835
6836
        $term = Database::escape_string($term);
6837
        $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
6838
        if (is_array($extraFieldsToInclude) && count($extraFieldsToInclude) > 0) {
6839
            $resultData = Database::select('*', $sTable, array(
6840
                'where' => array(
6841
                    "name LIKE %?% " => $term,
6842
                    " OR description LIKE %?% " => $term,
6843
                    " OR id IN (
6844
                    SELECT item_id
6845
                    FROM $sfvTable v INNER JOIN $extraFieldTable e
6846
                    ON (v.field_id = e.id)
6847
                    WHERE value LIKE %?% AND extra_field_type = $extraFieldType
6848
                ) " => $term,
6849
                ),
6850
            ));
6851
        } else {
6852
            $resultData = Database::select('*', $sTable, array(
6853
                'where' => array(
6854
                    "name LIKE %?% " => $term,
6855
                    "OR description LIKE %?% " => $term,
6856
                ),
6857
            ));
6858
6859
            return $resultData;
6860
        }
6861
6862
        foreach ($resultData as $id => &$session) {
6863
            $session['extra'] = self::getFilteredExtraFields($id, $extraFieldsToInclude);
6864
        }
6865
6866
        return $resultData;
6867
    }
6868
6869
    /**
6870
     * @param $sessionId
6871
     * @param array $extraFieldsToInclude
6872
     * @return array
6873
     */
6874
    public static function getFilteredExtraFields($sessionId, $extraFieldsToInclude = array())
6875
    {
6876
        $extraData = array();
6877
6878
        $variables = array();
6879
        $variablePlaceHolders = array();
6880
6881
        foreach ($extraFieldsToInclude as $sessionExtraField) {
6882
            $variablePlaceHolders[] = "?";
6883
            $variables[] = Database::escape_string($sessionExtraField);
6884
        }
6885
6886
        $sessionExtraField = new ExtraFieldModel('session');
6887
        $fieldList = $sessionExtraField->get_all(array(
6888
            "variable IN ( " . implode(", ", $variablePlaceHolders) . " ) " => $variables,
6889
        ));
6890
6891
        $fields = array();
6892
6893
        // Index session fields
6894
        foreach ($fieldList as $field) {
6895
            $fields[$field['id']] = $field['variable'];
6896
        }
6897
6898
        // Get session field values
6899
        $extra = new ExtraFieldValue('session');
6900
        $sessionFieldValueList = $extra->get_all(
6901
            array(
6902
                "field_id IN ( " . implode(", ", $variablePlaceHolders) . " )" => array_keys($fields),
6903
            )
6904
        );
6905
6906
        foreach ($sessionFieldValueList as $sessionFieldValue) {
6907
            // Match session field values to session
6908
            if ($sessionFieldValue['item_id'] != $sessionId) {
6909
                continue;
6910
            }
6911
6912
            // Check if session field value is set in session field list
6913
            if (!isset($fields[$sessionFieldValue['field_id']])) {
6914
                continue;
6915
            }
6916
6917
            $extrafieldVariable = $fields[$sessionFieldValue['field_id']];
6918
            $extrafieldValue = $sessionFieldValue['value'];
6919
6920
            $extraData[] = array(
6921
                'variable' => $extrafieldVariable,
6922
                'value' => $extrafieldValue,
6923
            );
6924
        }
6925
6926
        return $extraData;
6927
    }
6928
6929
    /**
6930
     * @param int $sessionId
6931
     *
6932
     * @return bool
6933
     */
6934
    public static function isValidId($sessionId)
6935
    {
6936
        $sessionId = intval($sessionId);
6937
        if ($sessionId > 0) {
6938
            $rows = Database::select(
6939
                'id',
6940
                Database::get_main_table(TABLE_MAIN_SESSION),
6941
                array('where' => array('id = ?' => $sessionId))
6942
            );
6943
            if (!empty($rows)) {
6944
6945
                return true;
6946
            }
6947
        }
6948
6949
        return false;
6950
    }
6951
6952
    /**
6953
     * Get list of sessions based on users of a group for a group admin
6954
     * @param int $userId The user id
6955
     * @return array
6956
     */
6957 View Code Duplication
    public static function getSessionsFollowedForGroupAdmin($userId)
6958
    {
6959
        $sessionList = array();
6960
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
6961
        $sessionUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6962
        $userGroup = new UserGroup();
6963
        $userIdList = $userGroup->getGroupUsersByUser($userId);
6964
6965
        if (empty($userIdList)) {
6966
            return [];
6967
        }
6968
6969
        $sql = "SELECT DISTINCT s.*
6970
                FROM $sessionTable s
6971
                INNER JOIN $sessionUserTable sru 
6972
                ON s.id = sru.id_session
6973
                WHERE
6974
                    (sru.id_user IN (" . implode(', ', $userIdList) . ")
6975
                    AND sru.relation_type = 0
6976
                )";
6977
6978
        if (api_is_multiple_url_enabled()) {
6979
            $sessionAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
6980
            $accessUrlId = api_get_current_access_url_id();
6981
6982
            if ($accessUrlId != -1) {
6983
                $sql = "SELECT DISTINCT s.*
6984
                        FROM $sessionTable s
6985
                        INNER JOIN $sessionUserTable sru ON s.id = sru.id_session
6986
                        INNER JOIN $sessionAccessUrlTable srau ON s.id = srau.session_id
6987
                        WHERE
6988
                            srau.access_url_id = $accessUrlId
6989
                            AND (
6990
                                sru.id_user IN (" . implode(', ', $userIdList) . ")
6991
                                AND sru.relation_type = 0
6992
                            )";
6993
            }
6994
        }
6995
6996
        $result = Database::query($sql);
6997
6998
        while ($row = Database::fetch_assoc($result)) {
6999
            $sessionList[] = $row;
7000
        }
7001
7002
        return $sessionList;
7003
    }
7004
7005
    /**
7006
     * @param array $sessionInfo
7007
     * @return string
7008
     */
7009
    public static function getSessionVisibility($sessionInfo)
7010
    {
7011
        switch ($sessionInfo['visibility']) {
7012
            case 1:
7013
                return get_lang('ReadOnly');
7014
            case 2:
7015
               return get_lang('Visible');
7016
            case 3:
7017
                return api_ucfirst(get_lang('Invisible'));
7018
        }
7019
    }
7020
7021
    /**
7022
     * Converts "start date" and "end date" to "From start date to end date" string
7023
     * @param string $startDate
7024
     * @param string $endDate
7025
     * @param bool $showTime
7026
     * @param bool $dateHuman
7027
     *
7028
     * @return string
7029
     */
7030
    private static function convertSessionDateToString($startDate, $endDate, $showTime, $dateHuman)
7031
    {
7032
        // api_get_local_time returns empty if date is invalid like 0000-00-00 00:00:00
7033
        $startDateToLocal = api_get_local_time(
7034
            $startDate,
7035
            null,
7036
            null,
7037
            true,
7038
            $showTime,
7039
            $dateHuman
7040
        );
7041
        $endDateToLocal = api_get_local_time(
7042
            $endDate,
7043
            null,
7044
            null,
7045
            true,
7046
            $showTime,
7047
            $dateHuman
7048
        );
7049
7050
        $result = '';
7051
        if (!empty($startDateToLocal) && !empty($endDateToLocal)) {
7052
            $result = sprintf(
7053
                get_lang('FromDateXToDateY'),
7054
                api_format_date($startDateToLocal, DATE_TIME_FORMAT_LONG_24H),
7055
                api_format_date($endDateToLocal, DATE_TIME_FORMAT_LONG_24H)
7056
            );
7057
        } else {
7058
            if (!empty($startDateToLocal)) {
7059
                $result = get_lang('From').' '.api_format_date($startDateToLocal, DATE_TIME_FORMAT_LONG_24H);
7060
            }
7061
            if (!empty($endDateToLocal)) {
7062
                $result = get_lang('Until').' '.api_format_date($endDateToLocal, DATE_TIME_FORMAT_LONG_24H);
7063
            }
7064
        }
7065
        if (empty($result)) {
7066
            $result = get_lang('NoTimeLimits');
7067
        }
7068
7069
        return $result;
7070
    }
7071
7072
    /**
7073
     * Returns a human readable string
7074
     * @params array $sessionInfo An array with all the session dates
7075
     * @return string
7076
     */
7077
    public static function parseSessionDates($sessionInfo, $showTime = false)
7078
    {
7079
        $displayDates = self::convertSessionDateToString(
7080
            $sessionInfo['display_start_date'],
7081
            $sessionInfo['display_end_date'],
7082
            $showTime,
7083
            true
7084
        );
7085
        $accessDates = self::convertSessionDateToString(
7086
            $sessionInfo['access_start_date'],
7087
            $sessionInfo['access_end_date'],
7088
            $showTime,
7089
            true
7090
        );
7091
7092
        $coachDates = self::convertSessionDateToString(
7093
            $sessionInfo['coach_access_start_date'],
7094
            $sessionInfo['coach_access_end_date'],
7095
            $showTime,
7096
            true
7097
        );
7098
7099
        $result = [
7100
            'access' => $accessDates,
7101
            'display' => $displayDates,
7102
            'coach' => $coachDates
7103
        ];
7104
7105
        return $result;
7106
    }
7107
7108
    /**
7109
     * @param FormValidator $form
7110
     * @param array $sessionInfo Optional
7111
     * @return array
7112
     */
7113
    public static function setForm(FormValidator $form, array $sessionInfo = [])
7114
    {
7115
        $sessionId = 0;
7116
        $coachInfo = [];
7117
7118
        if (!empty($sessionInfo)) {
7119
            $sessionId = intval($sessionInfo['id']);
7120
            $coachInfo = api_get_user_info($sessionInfo['id_coach']);
7121
        };
7122
7123
        $categoriesList = self::get_all_session_category();
7124
        $userInfo = api_get_user_info();
7125
7126
        $categoriesOptions = array(
7127
            '0' => get_lang('None'),
7128
        );
7129
7130
        if ($categoriesList != false) {
7131
            foreach ($categoriesList as $categoryItem) {
7132
                $categoriesOptions[$categoryItem['id']] = $categoryItem['name'];
7133
            }
7134
        }
7135
7136
        // Database Table Definitions
7137
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
7138
7139
        $form->addText(
7140
            'name',
7141
            get_lang('SessionName'),
7142
            true,
7143
            ['maxlength' => 150]
7144
        );
7145
        $form->addRule('name', get_lang('SessionNameAlreadyExists'), 'callback', 'check_session_name');
7146
7147
        if (!api_is_platform_admin() && api_is_teacher()) {
7148
            $form->addElement(
7149
                'select',
7150
                'coach_username',
7151
                get_lang('CoachName'),
7152
                [api_get_user_id() => $userInfo['complete_name']],
7153
                array(
7154
                    'id' => 'coach_username',
7155
                    'style' => 'width:370px;',
7156
                )
7157
            );
7158
        } else {
7159
            $sql = "SELECT COUNT(1) FROM $tbl_user WHERE status = 1";
7160
            $rs = Database::query($sql);
7161
            $countUsers = Database::result($rs, 0, 0);
7162
7163
            if (intval($countUsers) < 50) {
7164
                $orderClause = "ORDER BY ";
7165
                $orderClause .= api_sort_by_first_name() ? "firstname, lastname, username" : "lastname, firstname, username";
7166
7167
                $sql = "SELECT user_id, lastname, firstname, username
7168
                        FROM $tbl_user
7169
                        WHERE status = '1' ".
7170
                        $orderClause;
7171
7172
                if (api_is_multiple_url_enabled()) {
7173
                    $userRelAccessUrlTable = Database::get_main_table(
7174
                        TABLE_MAIN_ACCESS_URL_REL_USER
7175
                    );
7176
                    $accessUrlId = api_get_current_access_url_id();
7177
7178
                    if ($accessUrlId != -1) {
7179
                        $sql = "SELECT user.user_id, username, lastname, firstname
7180
                        FROM $tbl_user user
7181
                        INNER JOIN $userRelAccessUrlTable url_user
7182
                        ON (url_user.user_id = user.user_id)
7183
                        WHERE
7184
                            access_url_id = $accessUrlId AND
7185
                            status = 1 "
7186
                            .$orderClause;
7187
                    }
7188
                }
7189
7190
                $result = Database::query($sql);
7191
                $coachesList = Database::store_result($result);
7192
7193
                $coachesOptions = array();
7194 View Code Duplication
                foreach ($coachesList as $coachItem) {
7195
                    $coachesOptions[$coachItem['user_id']] =
7196
                        api_get_person_name($coachItem['firstname'], $coachItem['lastname']).' ('.$coachItem['username'].')';
7197
                }
7198
7199
                $form->addElement(
7200
                    'select',
7201
                    'coach_username',
7202
                    get_lang('CoachName'),
7203
                    $coachesOptions
7204
                );
7205
            } else {
7206
                $form->addElement(
7207
                    'select_ajax',
7208
                    'coach_username',
7209
                    get_lang('CoachName'),
7210
                    $coachInfo ? [$coachInfo['id'] => $coachInfo['complete_name_with_username']] : [],
7211
                    [
7212
                        'url' => api_get_path(WEB_AJAX_PATH) . 'session.ajax.php?a=search_general_coach',
7213
                        'width' => '100%',
7214
                    ]
7215
                );
7216
            }
7217
        }
7218
7219
        $form->addRule('coach_username', get_lang('ThisFieldIsRequired'), 'required');
7220
        $form->addHtml('<div id="ajax_list_coachs"></div>');
7221
7222
        $form->addButtonAdvancedSettings('advanced_params');
7223
        $form->addElement('html','<div id="advanced_params_options" style="display:none">');
7224
7225
        $form->addSelect(
7226
            'session_category',
7227
            get_lang('SessionCategory'),
7228
            $categoriesOptions,
7229
            array(
7230
                'id' => 'session_category',
7231
            )
7232
        );
7233
7234
        $form->addHtmlEditor(
7235
            'description',
7236
            get_lang('Description'),
7237
            false,
7238
            false,
7239
            array(
7240
                'ToolbarSet' => 'Minimal',
7241
            )
7242
        );
7243
7244
        $form->addElement('checkbox', 'show_description', null, get_lang('ShowDescription'));
7245
7246
        $visibilityGroup = array();
7247
        $visibilityGroup[] = $form->createElement('select', 'session_visibility', null, array(
7248
            SESSION_VISIBLE_READ_ONLY => get_lang('SessionReadOnly'),
7249
            SESSION_VISIBLE => get_lang('SessionAccessible'),
7250
            SESSION_INVISIBLE => api_ucfirst(get_lang('SessionNotAccessible')),
7251
        ));
7252
        $form->addGroup(
7253
            $visibilityGroup,
7254
            'visibility_group',
7255
            get_lang('SessionVisibility'),
7256
            null,
7257
            false
7258
        );
7259
7260
        $options = [
7261
            0 => get_lang('ByDuration'),
7262
            1 => get_lang('ByDates'),
7263
        ];
7264
7265
        $form->addSelect('access', get_lang('Access'), $options, array(
7266
            'onchange' => 'accessSwitcher()',
7267
            'id' => 'access',
7268
        ));
7269
7270
        $form->addHtml('<div id="duration" style="display:none">');
7271
7272
        $form->addElement(
7273
            'number',
7274
            'duration',
7275
            array(
7276
                get_lang('SessionDurationTitle'),
7277
                get_lang('SessionDurationDescription'),
7278
            ),
7279
            array(
7280
                'maxlength' => 50,
7281
            )
7282
        );
7283
7284
        $form->addHtml('</div>');
7285
        $form->addHtml('<div id="date_fields" style="display:none">');
7286
7287
        // Dates
7288
        $form->addDateTimePicker(
7289
            'access_start_date',
7290
            array(get_lang('SessionStartDate'), get_lang('SessionStartDateComment')),
7291
            array('id' => 'access_start_date')
7292
        );
7293
7294
        $form->addDateTimePicker(
7295
            'access_end_date',
7296
            array(get_lang('SessionEndDate'), get_lang('SessionEndDateComment')),
7297
            array('id' => 'access_end_date')
7298
        );
7299
7300
        $form->addRule(
7301
            array('access_start_date', 'access_end_date'),
7302
            get_lang('StartDateMustBeBeforeTheEndDate'),
7303
            'compare_datetime_text',
7304
            '< allow_empty'
7305
        );
7306
7307
        $form->addDateTimePicker(
7308
            'display_start_date',
7309
            array(
7310
                get_lang('SessionDisplayStartDate'),
7311
                get_lang('SessionDisplayStartDateComment'),
7312
            ),
7313
            array('id' => 'display_start_date')
7314
        );
7315
7316
        $form->addDateTimePicker(
7317
            'display_end_date',
7318
            array(
7319
                get_lang('SessionDisplayEndDate'),
7320
                get_lang('SessionDisplayEndDateComment'),
7321
            ),
7322
            array('id' => 'display_end_date')
7323
        );
7324
7325
        $form->addRule(
7326
            array('display_start_date', 'display_end_date'),
7327
            get_lang('StartDateMustBeBeforeTheEndDate'),
7328
            'compare_datetime_text',
7329
            '< allow_empty'
7330
        );
7331
7332
        $form->addDateTimePicker(
7333
            'coach_access_start_date',
7334
            array(
7335
                get_lang('SessionCoachStartDate'),
7336
                get_lang('SessionCoachStartDateComment'),
7337
            ),
7338
            array('id' => 'coach_access_start_date')
7339
        );
7340
7341
        $form->addDateTimePicker(
7342
            'coach_access_end_date',
7343
            array(
7344
                get_lang('SessionCoachEndDate'),
7345
                get_lang('SessionCoachEndDateComment'),
7346
            ),
7347
            array('id' => 'coach_access_end_date')
7348
        );
7349
7350
        $form->addRule(
7351
            array('coach_access_start_date', 'coach_access_end_date'),
7352
            get_lang('StartDateMustBeBeforeTheEndDate'),
7353
            'compare_datetime_text',
7354
            '< allow_empty'
7355
        );
7356
7357
        $form->addElement('html', '</div>');
7358
7359
        $form->addCheckBox(
7360
            'send_subscription_notification',
7361
            [
7362
                get_lang('SendSubscriptionNotification'),
7363
                get_lang('SendAnEmailWhenAUserBeingSubscribed'),
7364
            ]
7365
        );
7366
7367
        // Extra fields
7368
        $extra_field = new ExtraFieldModel('session');
7369
        $extra = $extra_field->addElements($form, $sessionId);
7370
7371
        $form->addElement('html', '</div>');
7372
7373
        $js = $extra['jquery_ready_content'];
7374
7375
        return ['js' => $js];
7376
    }
7377
7378
    /**
7379
     * Gets the number of rows in the session table filtered through the given
7380
     * array of parameters
7381
     * @param array Array of options/filters/keys
7382
     * @return integer The number of rows, or false on wrong param
7383
     * @assert ('a') === false
7384
     */
7385
    static function get_count_admin_complete($options = array())
7386
    {
7387
        if (!is_array($options)) {
7388
            return false;
7389
        }
7390
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
7391
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
7392
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
7393
        $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
7394
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
7395
7396
        $where = 'WHERE 1 = 1 ';
7397
        $user_id = api_get_user_id();
7398
7399
        if (api_is_session_admin() &&
7400
            api_get_setting('allow_session_admins_to_see_all_sessions') == 'false'
7401
        ) {
7402
            $where.=" WHERE s.session_admin_id = $user_id ";
7403
        }
7404
7405 View Code Duplication
        if (!empty($options['where'])) {
7406
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
7407
            $options['where'] = str_replace("( session_active = '0' )", '1=1',  $options['where']);
7408
7409
            $options['where'] = str_replace(
7410
                array("AND session_active = '1'  )", " AND (  session_active = '1'  )"),
7411
                array(') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 " )
7412
                , $options['where']
7413
            );
7414
7415
            $options['where'] = str_replace(
7416
                array("AND session_active = '0'  )", " AND (  session_active = '0'  )"),
7417
                array(') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "),
7418
                $options['where']
7419
            );
7420
7421
            if (!empty($options['extra'])) {
7422
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
7423
                $options['where'] = str_replace('AND', 'OR', $options['where']);
7424
7425
                foreach ($options['extra'] as $extra) {
7426
                    $options['where'] = str_replace($extra['field'], 'fv.field_id = '.$extra['id'].' AND fvo.option_value', $options['where']);
7427
                }
7428
            }
7429
            $where .= ' AND '.$options['where'];
7430
        }
7431
7432
        $today = api_get_utc_datetime();
7433
        $query_rows = "SELECT count(*) as total_rows, c.title as course_title, s.name,
7434
                        IF (
7435
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
7436
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
7437
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
7438
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
7439
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
7440
                        , 1, 0) as session_active
7441
                       FROM $tbl_session s
7442
                       LEFT JOIN  $tbl_session_category sc
7443
                       ON s.session_category_id = sc.id
7444
                       INNER JOIN $tbl_user u
7445
                       ON s.id_coach = u.user_id
7446
                       INNER JOIN $sessionCourseUserTable scu
7447
                       ON s.id = scu.session_id
7448
                       INNER JOIN $courseTable c
7449
                       ON c.id = scu.c_id
7450
                       $where ";
7451
7452
        if (api_is_multiple_url_enabled()) {
7453
            $table_access_url_rel_session= Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
7454
            $access_url_id = api_get_current_access_url_id();
7455
            if ($access_url_id != -1) {
7456
                $where.= " AND ar.access_url_id = $access_url_id ";
7457
7458
                $query_rows = "SELECT count(*) as total_rows
7459
                               FROM $tbl_session s
7460
                               LEFT JOIN  $tbl_session_category sc
7461
                               ON s.session_category_id = sc.id
7462
                               INNER JOIN $tbl_user u
7463
                               ON s.id_coach = u.user_id
7464
                               INNER JOIN $table_access_url_rel_session ar
7465
                               ON ar.session_id = s.id $where ";
7466
            }
7467
        }
7468
7469
        $result = Database::query($query_rows);
7470
        $num = 0;
7471
        if (Database::num_rows($result)) {
7472
            $rows = Database::fetch_array($result);
7473
            $num = $rows['total_rows'];
7474
        }
7475
7476
        return $num;
7477
    }
7478
7479
    /**
7480
     * @param string $list_type
7481
     * @return array
7482
     */
7483
    public static function getGridColumns($list_type = 'simple')
7484
    {
7485
        // Column config
7486
        $operators = array('cn', 'nc');
7487
        $date_operators = array('gt', 'ge', 'lt', 'le');
7488
7489
        switch ($list_type) {
7490
            case 'simple':
7491
                $columns = array(
7492
                    get_lang('Name'),
7493
                    get_lang('Category'),
7494
                    get_lang('SessionDisplayStartDate'),
7495
                    get_lang('SessionDisplayEndDate'),
7496
                    //get_lang('Coach'),
7497
                    //get_lang('Status'),
7498
                    //get_lang('CourseTitle'),
7499
                    get_lang('Visibility'),
7500
                );
7501
                $column_model = array (
7502
                    array('name'=>'name', 'index'=>'s.name', 'width'=>'160',  'align'=>'left', 'search' => 'true', 'searchoptions' => array('sopt' => $operators)),
7503
                    array('name'=>'category_name', 'index'=>'category_name', 'width'=>'40',  'align'=>'left', 'search' => 'true', 'searchoptions' => array('sopt' => $operators)),
7504
                    array('name'=>'display_start_date', 'index'=>'display_start_date', 'width'=>'50',   'align'=>'left', 'search' => 'true', 'searchoptions' => array('dataInit' => 'date_pick_today', 'sopt' => $date_operators)),
7505
                    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)),
7506
                    array('name'=>'visibility', 'index'=>'visibility',      'width'=>'40',   'align'=>'left', 'search' => 'false'),
7507
                );
7508
                break;
7509
            case 'complete':
7510
                $columns = array(
7511
                    get_lang('Name'),
7512
                    get_lang('SessionDisplayStartDate'),
7513
                    get_lang('SessionDisplayEndDate'),
7514
                    get_lang('Coach'),
7515
                    get_lang('Status'),
7516
                    get_lang('Visibility'),
7517
                    get_lang('CourseTitle'),
7518
                );
7519
                $column_model = array (
7520
                    array('name'=>'name', 'index'=>'s.name', 'width'=>'200',  'align'=>'left', 'search' => 'true', 'searchoptions' => array('sopt' => $operators)),
7521
                    array('name'=>'display_start_date', 'index'=>'display_start_date', 'width'=>'70',   'align'=>'left', 'search' => 'true', 'searchoptions' => array('dataInit' => 'date_pick_today', 'sopt' => $date_operators)),
7522
                    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)),
7523
                    array('name'=>'coach_name', 'index'=>'coach_name',     'width'=>'70',   'align'=>'left', 'search' => 'false', 'searchoptions' => array('sopt' => $operators)),
7524
                    array('name'=>'session_active', 'index'=>'session_active', 'width'=>'25',   'align'=>'left', 'search' => 'true', 'stype'=>'select',
7525
                        // for the bottom bar
7526
                        'searchoptions' => array(
7527
                            'defaultValue'  => '1',
7528
                            'value'         => '1:'.get_lang('Active').';0:'.get_lang('Inactive')),
7529
                        // for the top bar
7530
                        'editoptions' => array('value' => '" ":'.get_lang('All').';1:'.get_lang('Active').';0:'.get_lang('Inactive')),
7531
                    ),
7532
                    array('name'=>'visibility',     'index'=>'visibility',      'width'=>'40',   'align'=>'left', 'search' => 'false'),
7533
                    array('name'=>'course_title',    'index'=>'course_title',   'width'=>'50',   'hidden' => 'true', 'search' => 'true', 'searchoptions' => array('searchhidden' =>'true','sopt' => $operators)),
7534
                );
7535
                break;
7536
        }
7537
7538
        // Inject extra session fields
7539
        $session_field = new ExtraFieldModel('session');
7540
        $rules = $session_field->getRules($columns, $column_model);
7541
7542
        $column_model[] = array(
7543
            'name' => 'actions',
7544
            'index' => 'actions',
7545
            'width' => '80',
7546
            'align' => 'left',
7547
            'formatter' => 'action_formatter',
7548
            'sortable' => 'false',
7549
            'search' => 'false',
7550
        );
7551
        $columns[] = get_lang('Actions');
7552
7553
        foreach ($column_model as $col_model) {
7554
            $simple_column_name[] = $col_model['name'];
7555
        }
7556
7557
        $return_array =  array(
7558
            'columns' => $columns,
7559
            'column_model' => $column_model,
7560
            'rules' => $rules,
7561
            'simple_column_name' => $simple_column_name,
7562
        );
7563
7564
        return $return_array;
7565
    }
7566
7567
    /**
7568
     * Converts all dates sent through the param array (given form) to correct dates with timezones
7569
     * @param array The dates The same array, with times converted
7570
     * @param boolean $applyFormat Whether apply the DATE_TIME_FORMAT_SHORT format for sessions
7571
     * @return array The same array, with times converted
7572
     */
7573
    static function convert_dates_to_local($params, $applyFormat = false)
7574
    {
7575
        if (!is_array($params)) {
7576
            return false;
7577
        }
7578
        $params['display_start_date'] = api_get_local_time($params['display_start_date'], null, null, true);
7579
        $params['display_end_date'] = api_get_local_time($params['display_end_date'], null, null, true);
7580
7581
        $params['access_start_date'] = api_get_local_time($params['access_start_date'], null, null, true);
7582
        $params['access_end_date'] = api_get_local_time($params['access_end_date'], null, null, true);
7583
7584
        $params['coach_access_start_date'] = isset($params['coach_access_start_date']) ? api_get_local_time($params['coach_access_start_date'], null, null, true) : null;
7585
        $params['coach_access_end_date'] = isset($params['coach_access_end_date']) ? api_get_local_time($params['coach_access_end_date'], null, null, true) : null;
7586
7587
        if ($applyFormat) {
7588 View Code Duplication
            if (isset($params['display_start_date'])) {
7589
                $params['display_start_date'] = api_format_date($params['display_start_date'], DATE_TIME_FORMAT_SHORT);
7590
            }
7591
7592 View Code Duplication
            if (isset($params['display_end_date'])) {
7593
                $params['display_end_date'] = api_format_date($params['display_end_date'], DATE_TIME_FORMAT_SHORT);
7594
            }
7595
7596 View Code Duplication
            if (isset($params['access_start_date'])) {
7597
                $params[''] = api_format_date($params['access_start_date'], DATE_TIME_FORMAT_SHORT);
7598
            }
7599
7600 View Code Duplication
            if (isset($params['access_end_date'])) {
7601
                $params['access_end_date'] = api_format_date($params['access_end_date'], DATE_TIME_FORMAT_SHORT);
7602
            }
7603
7604 View Code Duplication
            if (isset($params['coach_access_start_date'])) {
7605
                $params['coach_access_start_date'] = api_format_date($params['coach_access_start_date'], DATE_TIME_FORMAT_SHORT);
7606
            }
7607
7608 View Code Duplication
            if (isset($params['coach_access_end_date'])) {
7609
                $params['coach_access_end_date'] = api_format_date($params['coach_access_end_date'], DATE_TIME_FORMAT_SHORT);
7610
            }
7611
        }
7612
7613
        return $params;
7614
    }
7615
7616
    /**
7617
     * Gets the admin session list callback of the session/session_list.php
7618
     * page with all user/details in the right fomat
7619
     * @param array
7620
     * @result array Array of rows results
7621
     * @asset ('a') === false
7622
     */
7623
    public static function get_sessions_admin_complete($options = array())
7624
    {
7625
        if (!is_array($options)) {
7626
            return false;
7627
        }
7628
7629
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
7630
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
7631
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
7632
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
7633
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
7634
7635
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7636
        $tbl_session_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7637
        $tbl_session_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
7638
7639
        $where = 'WHERE 1 = 1 ';
7640
        $user_id = api_get_user_id();
7641
7642 View Code Duplication
        if (!api_is_platform_admin()) {
7643
            if (api_is_session_admin() &&
7644
                api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
7645
            ) {
7646
                $where.=" AND s.session_admin_id = $user_id ";
7647
            }
7648
        }
7649
7650
        $coach_name = " CONCAT(u.lastname , ' ', u.firstname) as coach_name ";
7651
        if (api_is_western_name_order()) {
7652
            $coach_name = " CONCAT(u.firstname, ' ', u.lastname) as coach_name ";
7653
        }
7654
7655
        $today = api_get_utc_datetime();
7656
        $inject_extra_fields = null;
7657
        $extra_fields = array();
7658
        $extra_fields_info = array();
7659
7660
        //for now only sessions
7661
        $extra_field = new ExtraFieldModel('session');
7662
        $double_fields = array();
7663
        $extra_field_option = new ExtraFieldOption('session');
7664
7665
        if (isset($options['extra'])) {
7666
            $extra_fields = $options['extra'];
7667
            if (!empty($extra_fields)) {
7668
                foreach ($extra_fields as $extra) {
7669
                    $inject_extra_fields .= " IF (fv.field_id = {$extra['id']}, fvo.option_display_text, NULL ) as {$extra['field']} , ";
7670 View Code Duplication
                    if (isset($extra_fields_info[$extra['id']])) {
7671
                        $info = $extra_fields_info[$extra['id']];
7672
                    } else {
7673
                        $info = $extra_field->get($extra['id']);
7674
                        $extra_fields_info[$extra['id']] = $info;
7675
                    }
7676
7677
                    if ($info['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) {
7678
                        $double_fields[$info['id']] = $info;
7679
                    }
7680
                }
7681
            }
7682
        }
7683
7684
        $options_by_double = array();
7685 View Code Duplication
        foreach ($double_fields as $double) {
7686
            $my_options = $extra_field_option->get_field_options_by_field(
7687
                $double['id'],
7688
                true
7689
            );
7690
            $options_by_double['extra_'.$double['field_variable']] = $my_options;
7691
        }
7692
7693
        //sc.name as category_name,
7694
        $select = "
7695
                SELECT * FROM (
7696
                    SELECT DISTINCT
7697
                         IF (
7698
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
7699
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
7700
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
7701
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
7702
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
7703
                        , 1, 0) as session_active,
7704
                s.name,
7705
                s.nbr_courses,
7706
                s.nbr_users,
7707
                s.display_start_date,
7708
                s.display_end_date,
7709
                $coach_name,
7710
                access_start_date,
7711
                access_end_date,
7712
                s.visibility,
7713
                u.user_id,
7714
                $inject_extra_fields
7715
                c.title as course_title,
7716
                s.id ";
7717
7718 View Code Duplication
        if (!empty($options['where'])) {
7719
            if (!empty($options['extra'])) {
7720
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
7721
                $options['where'] = str_replace('AND', 'OR', $options['where']);
7722
                foreach ($options['extra'] as $extra) {
7723
                    $options['where'] = str_replace($extra['field'], 'fv.field_id = '.$extra['id'].' AND fvo.option_value', $options['where']);
7724
                }
7725
            }
7726
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
7727
7728
            $options['where'] = str_replace("( session_active = '0' )", '1=1',  $options['where']);
7729
7730
            $options['where'] = str_replace(
7731
                array("AND session_active = '1'  )", " AND (  session_active = '1'  )"),
7732
                array(') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 " )
7733
                , $options['where']
7734
            );
7735
7736
            $options['where'] = str_replace(
7737
                array("AND session_active = '0'  )", " AND (  session_active = '0'  )"),
7738
                array(') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "),
7739
                $options['where']
7740
            );
7741
7742
7743
            $where .= ' AND '.$options['where'];
7744
        }
7745
7746
        if (!empty($options['limit'])) {
7747
            $where .= " LIMIT ".$options['limit'];
7748
        }
7749
        $query = "$select FROM $tbl_session s
7750
                    LEFT JOIN $tbl_session_field_values fv
7751
                    ON (fv.item_id = s.id)
7752
                    LEFT JOIN $extraFieldTable f
7753
                    ON f.id = fv.field_id
7754
                    LEFT JOIN $tbl_session_field_options fvo
7755
                    ON (fv.field_id = fvo.field_id)
7756
                    LEFT JOIN $tbl_session_rel_course src
7757
                    ON (src.session_id = s.id)
7758
                    LEFT JOIN $tbl_course c
7759
                    ON (src.c_id = c.id)
7760
                    LEFT JOIN $tbl_session_category sc
7761
                    ON (s.session_category_id = sc.id)
7762
                    INNER JOIN $tbl_user u
7763
                    ON (s.id_coach = u.user_id) ".
7764
            $where;
7765
7766 View Code Duplication
        if (api_is_multiple_url_enabled()) {
7767
            $table_access_url_rel_session= Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
7768
            $access_url_id = api_get_current_access_url_id();
7769
            if ($access_url_id != -1) {
7770
                $where.= " AND ar.access_url_id = $access_url_id ";
7771
                $query = "$select
7772
                    FROM $tbl_session s
7773
                    LEFT JOIN $tbl_session_field_values fv ON (fv.session_id = s.id)
7774
                    LEFT JOIN $tbl_session_field_options fvo ON (fv.field_id = fvo.field_id)
7775
                    LEFT JOIN $tbl_session_rel_course src ON (src.id_session = s.id)
7776
                    LEFT JOIN $tbl_course c ON (src.c_id = c.id)
7777
                    LEFT JOIN $tbl_session_category sc ON (s.session_category_id = sc.id)
7778
                    INNER JOIN $tbl_user u ON (s.id_coach = u.user_id)
7779
                    INNER JOIN $table_access_url_rel_session ar ON (ar.session_id = s.id)
7780
                    $where";
7781
            }
7782
        }
7783
7784
        $query .= ") AS session_table";
7785
7786
        if (!empty($options['order'])) {
7787
            $query .= " ORDER BY ".$options['order'];
7788
        }
7789
7790
        $result = Database::query($query);
7791
        $formatted_sessions = array();
7792
7793
        if (Database::num_rows($result)) {
7794
            $sessions   = Database::store_result($result, 'ASSOC');
7795
            foreach ($sessions as $session) {
7796
                $session_id = $session['id'];
7797
                $session['name'] = Display::url($session['name'], "resume_session.php?id_session=".$session['id']);
7798
                $session['coach_name'] = Display::url($session['coach_name'], "user_information.php?user_id=".$session['user_id']);
7799 View Code Duplication
                if ($session['session_active'] == 1) {
7800
                    $session['session_active'] = Display::return_icon('accept.png', get_lang('Active'), array(), ICON_SIZE_SMALL);
7801
                } else {
7802
                    $session['session_active'] = Display::return_icon('error.png', get_lang('Inactive'), array(), ICON_SIZE_SMALL);
7803
                }
7804
7805
                $session = self::convert_dates_to_local($session);
7806
7807 View Code Duplication
                switch ($session['visibility']) {
7808
                    case SESSION_VISIBLE_READ_ONLY: //1
7809
                        $session['visibility'] =  get_lang('ReadOnly');
7810
                        break;
7811
                    case SESSION_VISIBLE:           //2
7812
                    case SESSION_AVAILABLE:         //4
7813
                        $session['visibility'] =  get_lang('Visible');
7814
                        break;
7815
                    case SESSION_INVISIBLE:         //3
7816
                        $session['visibility'] =  api_ucfirst(get_lang('Invisible'));
7817
                        break;
7818
                }
7819
7820
                // Cleaning double selects
7821 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...
7822
                    if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
7823
                        $options = explode('::', $value);
7824
                    }
7825
                    $original_key = $key;
7826
7827
                    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...
7828
                    } else {
7829
                        $key = str_replace('_second', '', $key);
7830
                    }
7831
7832
                    if (isset($options_by_double[$key])) {
7833
                        if (isset($options[0])) {
7834
                            if (isset($options_by_double[$key][$options[0]])) {
7835
                                if (strpos($original_key, '_second') === false) {
7836
                                    $value = $options_by_double[$key][$options[0]]['option_display_text'];
7837
                                } else {
7838
                                    $value = $options_by_double[$key][$options[1]]['option_display_text'];
7839
                                }
7840
                            }
7841
                        }
7842
                    }
7843
                }
7844
7845
                // Magic filter
7846
                if (isset($formatted_sessions[$session_id])) {
7847
                    $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 7805 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...
7848
                } else {
7849
                    $formatted_sessions[$session_id] = $session;
7850
                }
7851
            }
7852
        }
7853
7854
        return $formatted_sessions;
7855
    }
7856
7857
    /**
7858
     * Compare two arrays
7859
     * @param array $array1
7860
     * @param array $array2
7861
     *
7862
     * @return array
7863
     */
7864
    static function compareArraysToMerge($array1, $array2)
7865
    {
7866
        if (empty($array2)) {
7867
            return $array1;
7868
        }
7869
        foreach ($array1 as $key => $item) {
7870
            if (!isset($array1[$key])) {
7871
                //My string is empty try the other one
7872
                if (isset($array2[$key]) && !empty($array2[$key])) {
7873
                    $array1[$key] = $array2[$key];
7874
                }
7875
            }
7876
        }
7877
        return $array1;
7878
    }
7879
7880
    /**
7881
     * Get link to the admin page for this session
7882
     * @param   int $id Session ID
7883
     * @return mixed    URL to the admin page to manage the session, or false on error
7884
     */
7885
    public static function getAdminPath($id)
7886
    {
7887
        $id = intval($id);
7888
        $session = self::fetch($id);
7889
        if (empty($session)) {
7890
            return false;
7891
        }
7892
        return api_get_path(WEB_CODE_PATH) . 'session/resume_session.php?id_session=' . $id;
7893
    }
7894
7895
    /**
7896
     * Get link to the user page for this session.
7897
     * If a course is provided, build the link to the course
7898
     * @param   int $id Session ID
7899
     * @param   int $courseId Course ID (optional) in case the link has to send straight to the course
7900
     * @return mixed    URL to the page to use the session, or false on error
7901
     */
7902
    public static function getPath($id, $courseId = 0)
7903
    {
7904
        $id = intval($id);
7905
        $session = self::fetch($id);
7906
        if (empty($session)) {
7907
            return false;
7908
        }
7909
        if (empty($courseId)) {
7910
            return api_get_path(WEB_CODE_PATH) . 'session/index.php?session_id=' . $id;
7911
        } else {
7912
            $courseInfo = api_get_course_info_by_id($courseId);
7913
            if ($courseInfo) {
7914
                return $courseInfo['course_public_url'].'?id_session='.$id;
7915
            }
7916
        }
7917
7918
        return false;
7919
    }
7920
7921
    /**
7922
     * Return an associative array 'id_course' => [id_session1, id_session2...]
7923
     * where course id_course is in sessions id_session1, id_session2
7924
     * for course where user is coach
7925
     * i.e. coach for the course or
7926
     * main coach for a session the course is in
7927
     * for a session category (or woth no session category if empty)
7928
     *
7929
     * @param $userId
7930
     *
7931
     * @return array
7932
     */
7933
    public static function getSessionCourseForUser($userId)
7934
    {
7935
        // list of COURSES where user is COURSE session coach
7936
        $listCourseCourseCoachSession = self::getCoursesForCourseSessionCoach($userId);
7937
7938
        // list of courses where user is MAIN session coach
7939
        $listCourseMainCoachSession = self::getCoursesForMainSessionCoach($userId);
7940
7941
        // merge these 2 array
7942
        $listResCourseSession = $listCourseCourseCoachSession;
7943
        foreach ($listCourseMainCoachSession as $courseId2 => $listSessionId2) {
7944
            if (isset($listResCourseSession[$courseId2])) {
7945
                // if sessionId array exists for this course
7946
                // same courseId, merge the list of session
7947
                foreach ($listCourseMainCoachSession[$courseId2] as $i => $sessionId2) {
7948
                    if (!in_array($sessionId2, $listResCourseSession[$courseId2])) {
7949
                        $listResCourseSession[$courseId2][] = $sessionId2;
7950
                    }
7951
                }
7952
            } else {
7953
                $listResCourseSession[$courseId2] = $listSessionId2;
7954
            }
7955
        }
7956
7957
        return $listResCourseSession;
7958
    }
7959
7960
    /**
7961
     * Return an associative array 'id_course' => [id_session1, id_session2...]
7962
     * where course id_course is in sessions id_session1, id_session2
7963
     * @param $userId
7964
     *
7965
     * @return array
7966
     */
7967
    public static function getCoursesForCourseSessionCoach($userId)
7968
    {
7969
        $listResCourseSession = array();
7970
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
7971
        $tblSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
7972
7973
        $sql = "SELECT session_id, c_id, c.id
7974
                FROM $tblSessionRelCourseRelUser srcru
7975
                LEFT JOIN $tblCourse c
7976
                ON c.id = srcru.c_id
7977
                WHERE
7978
                    srcru.user_id =".intval($userId)." AND
7979
                    srcru.status = 2";
7980
7981
        $res = Database::query($sql);
7982
7983
        while ($data = Database::fetch_assoc($res)) {
7984
            if (api_get_session_visibility($data['session_id'])) {
7985
                if (!isset($listResCourseSession[$data['id']])) {
7986
                    $listResCourseSession[$data['id']] = array();
7987
                }
7988
                $listResCourseSession[$data['id']][] = $data['session_id'];
7989
            }
7990
        }
7991
7992
        return $listResCourseSession;
7993
    }
7994
7995
    /**
7996
     * Return an associative array 'id_course' => [id_session1, id_session2...]
7997
     * where course id_course is in sessions id_session1, id_session2
7998
     * @param $userId
7999
     *
8000
     * @return array
8001
     */
8002
    public static function getCoursesForMainSessionCoach($userId)
8003
    {
8004
        $listResCourseSession = array();
8005
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
8006
8007
        // list of SESSION where user is session coach
8008
        $sql = "SELECT id FROM $tblSession
8009
                WHERE id_coach = ".intval($userId);
8010
        $res = Database::query($sql);
8011
8012
        while ($data = Database::fetch_assoc($res)) {
8013
            $sessionId = $data['id'];
8014
            $listCoursesInSession = self::getCoursesInSession($sessionId);
8015
            foreach ($listCoursesInSession as $i => $courseId) {
8016
                if (api_get_session_visibility($sessionId)) {
8017
                    if (!isset($listResCourseSession[$courseId])) {
8018
                        $listResCourseSession[$courseId] = array();
8019
                    }
8020
                    $listResCourseSession[$courseId][] = $sessionId;
8021
                }
8022
            }
8023
        }
8024
8025
        return $listResCourseSession;
8026
    }
8027
8028
    /**
8029
     * Return an array of course_id used in session $sessionId
8030
     * @param $sessionId
8031
     *
8032
     * @return array
8033
     */
8034 View Code Duplication
    public static function getCoursesInSession($sessionId)
8035
    {
8036
        if (empty($sessionId)) {
8037
            return [];
8038
        }
8039
8040
        $tblSessionRelCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
8041
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
8042
8043
        // list of course in this session
8044
        $sql = "SELECT session_id, c.id
8045
                FROM $tblSessionRelCourse src
8046
                LEFT JOIN $tblCourse c
8047
                ON c.id = src.c_id
8048
                WHERE session_id = ".intval($sessionId);
8049
        $res = Database::query($sql);
8050
8051
        $listResultsCourseId = array();
8052
        while ($data = Database::fetch_assoc($res)) {
8053
            $listResultsCourseId[] = $data['id'];
8054
        }
8055
8056
        return $listResultsCourseId;
8057
    }
8058
8059
    /**
8060
     * Return an array of courses in session for user
8061
     * and for each courses the list of session that use this course for user
8062
     *
8063
     * [0] => array
8064
     *      userCatId
8065
     *      userCatTitle
8066
     *      courseInUserCatList
8067
     *          [0] => array
8068
     *              courseId
8069
     *              title
8070
     *              courseCode
8071
     *              sessionCatList
8072
     *                  [0] => array
8073
     *                      catSessionId
8074
     *                      catSessionName
8075
     *                      sessionList
8076
     *                          [0] => array
8077
     *                              sessionId
8078
     *                              sessionName
8079
     *
8080
     * @param $userId
8081
     *
8082
     * @return array
8083
     *
8084
     */
8085
    public static function getNamedSessionCourseForCoach($userId)
8086
    {
8087
        $listResults = array();
8088
        $listCourseSession = self::getSessionCourseForUser($userId);
8089
        foreach ($listCourseSession as $courseId => $listSessionId) {
8090
            // Course info
8091
            $courseInfo = api_get_course_info_by_id($courseId);
8092
            $listOneCourse = array();
8093
            $listOneCourse['courseId'] = $courseId;
8094
            $listOneCourse['title'] = $courseInfo['title'];
8095
            //$listOneCourse['courseCode'] = $courseInfo['code'];
8096
            $listOneCourse['course'] = $courseInfo;
8097
            $listOneCourse['sessionCatList'] = array();
8098
            $listCat = array();
8099
            foreach ($listSessionId as $i => $sessionId) {
8100
                // here we got all session for this course
8101
                // lets check there session categories
8102
                $sessionInfo = self::fetch($sessionId);
8103
                $catId = $sessionInfo['session_category_id'];
8104
                if (!isset($listCat[$catId])) {
8105
                    $listCatInfo = self::get_session_category($catId);
8106
                    $listCat[$catId] = array();
8107
                    $listCat[$catId]['catSessionId'] = $catId;
8108
                    $listCat[$catId]['catSessionName'] = $listCatInfo['name'];
8109
                    $listCat[$catId]['sessionList'] = array();
8110
                }
8111
                $listSessionInfo = self::fetch($sessionId);
8112
                $listSessionIdName = array(
8113
                    "sessionId" => $sessionId,
8114
                    "sessionName" => $listSessionInfo['name'],
8115
                );
8116
                $listCat[$catId]['sessionList'][] = $listSessionIdName;
8117
            }
8118
            // sort $listCat by catSessionName
8119
            usort($listCat, 'self::compareBySessionName');
8120
            // in each catSession sort sessionList by sessionName
8121
            foreach($listCat as $i => $listCatSessionInfo) {
8122
                $listSessionList = $listCatSessionInfo['sessionList'];
8123
                usort($listSessionList, 'self::compareCatSessionInfo');
8124
                $listCat[$i]['sessionList'] = $listSessionList;
8125
            }
8126
8127
            $listOneCourse['sessionCatList'] = $listCat;
8128
8129
            // user course category
8130
            $courseCategory = CourseManager::getUserCourseCategoryForCourse(
8131
                $userId,
8132
                $courseId
8133
            );
8134
8135
            $userCatTitle = '';
8136
            $userCatId = 0;
8137
            if ($courseCategory) {
8138
                $userCatId = $courseCategory['user_course_cat'];
8139
                $userCatTitle = $courseCategory['title'];
8140
            }
8141
8142
            $listResults[$userCatId]['courseInUserCategoryId'] =  $userCatId;
8143
            $listResults[$userCatId]['courseInUserCategoryTitle'] =  $userCatTitle;
8144
            $listResults[$userCatId]['courseInUserCatList'][] = $listOneCourse;
8145
        }
8146
8147
        // sort by user course cat
8148
        uasort($listResults, 'self::compareByUserCourseCat');
8149
8150
        // sort by course title
8151
        foreach ($listResults as $userCourseCatId => $tabCoursesInCat) {
8152
            $courseInUserCatList = $tabCoursesInCat['courseInUserCatList'];
8153
            uasort($courseInUserCatList, 'self::compareByCourse');
8154
            $listResults[$userCourseCatId]['courseInUserCatList'] = $courseInUserCatList;
8155
        }
8156
8157
        return $listResults;
8158
    }
8159
8160
    /**
8161
     * @param array $listA
8162
     * @param array $listB
8163
     * @return int
8164
     */
8165 View Code Duplication
    private static function compareCatSessionInfo($listA, $listB)
8166
    {
8167
        if ($listA['sessionName'] == $listB['sessionName']) {
8168
            return 0;
8169
        } elseif ($listA['sessionName'] > $listB['sessionName']) {
8170
            return 1;
8171
        } else {
8172
            return -1;
8173
        }
8174
    }
8175
8176
    /**
8177
     * @param array $listA
8178
     * @param array $listB
8179
     * @return int
8180
     */
8181
    private static function compareBySessionName($listA, $listB)
8182
    {
8183
        if ($listB['catSessionName'] == '') {
8184
            return -1;
8185
        } else if ($listA['catSessionName'] == '') {
8186
            return 1;
8187
        } else if ($listA['catSessionName'] == $listB['catSessionName']) {
8188
            return 0;
8189
        } else if ($listA['catSessionName'] > $listB['catSessionName']) {
8190
            return 1;
8191
        } else {
8192
            return -1;
8193
        }
8194
    }
8195
8196
    /**
8197
     * @param array $listA
8198
     * @param array $listB
8199
     * @return int
8200
     */
8201 View Code Duplication
    private static function compareByUserCourseCat($listA, $listB)
8202
    {
8203
        if ($listA['courseInUserCategoryTitle'] == $listB['courseInUserCategoryTitle']) {
8204
            return 0;
8205
        } else if ($listA['courseInUserCategoryTitle'] > $listB['courseInUserCategoryTitle']) {
8206
            return 1;
8207
        } else {
8208
            return -1;
8209
        }
8210
    }
8211
8212
    /**
8213
     * @param array $listA
8214
     * @param array $listB
8215
     * @return int
8216
     */
8217 View Code Duplication
    private static function compareByCourse($listA, $listB)
8218
    {
8219
        if ($listA['title'] == $listB['title']) {
8220
            return 0;
8221
        } else if ($listA['title'] > $listB['title']) {
8222
            return 1;
8223
        } else {
8224
            return -1;
8225
        }
8226
    }
8227
8228
    /**
8229
     * Return HTML code for displaying session_course_for_coach
8230
     * @param $userId
8231
     * @return string
8232
     */
8233
    public static function getHtmlNamedSessionCourseForCoach($userId)
8234
    {
8235
        $htmlRes = '';
8236
        $listInfo = self::getNamedSessionCourseForCoach($userId);
8237
        foreach ($listInfo as $i => $listCoursesInfo) {
8238
            $courseInfo = $listCoursesInfo['course'];
8239
            $courseCode = $listCoursesInfo['course']['code'];
8240
8241
            $listParamsCourse = array();
8242
            $listParamsCourse['icon'] = '<div style="float:left">
8243
                <input style="border:none;" type="button" onclick="$(\'#course-'.$courseCode.'\').toggle(\'fast\')" value="+" /></div>'.
8244
                Display::return_icon('blackboard.png', $courseInfo['title'], array(), ICON_SIZE_LARGE);
8245
            $listParamsCourse['link'] = '';
8246
            $listParamsCourse['title'] = Display::tag(
8247
                'a',
8248
                $courseInfo['title'],
8249
                array('href' => $listParamsCourse['link'])
8250
            );
8251
            $htmlCourse = '<div class="well" style="border-color:#27587D">'.
8252
                CourseManager::course_item_html($listParamsCourse, true);
8253
            // for each category of session
8254
            $htmlCatSessions = '';
8255
            foreach ($listCoursesInfo['sessionCatList'] as $j => $listCatSessionsInfo) {
8256
                // we got an array of session categories
8257
                $catSessionId = $listCoursesInfo['sessionCatList'][$j]['catSessionId'];
8258
                $catSessionName = $listCoursesInfo['sessionCatList'][$j]['catSessionName'];
8259
8260
                $listParamsCatSession['icon'] = Display::return_icon('folder_blue.png', $catSessionName, array(), ICON_SIZE_LARGE);
8261
                $listParamsCatSession['link'] = '';
8262
                $listParamsCatSession['title'] = $catSessionName;
8263
8264
                $marginShift = 20;
8265
                if ($catSessionName != '') {
8266
                    $htmlCatSessions .= '<div style="margin-left:'.$marginShift.'px;">' .
8267
                        CourseManager::course_item_html($listParamsCatSession, true) . '</div>';
8268
                    $marginShift = 40;
8269
                }
8270
8271
                // for each sessions
8272
                $listCatSessionSessionList = $listCoursesInfo['sessionCatList'][$j]['sessionList'];
8273
                $htmlSession = '';
8274
                foreach ($listCatSessionSessionList as $k => $listSessionInfo) {
8275
                    // we got an array of session info
8276
                    $sessionId = $listSessionInfo['sessionId'];
8277
                    $sessionName = $listSessionInfo['sessionName'];
8278
8279
                    $listParamsSession['icon'] = Display::return_icon('blackboard_blue.png', $sessionName, array(), ICON_SIZE_LARGE);
8280
                    $listParamsSession['link'] = '';
8281
                    $linkToCourseSession = $courseInfo['course_public_url'].'?id_session='.$sessionId;
8282
                    $listParamsSession['title'] =
8283
                        $sessionName.'<div style="font-weight:normal; font-style:italic">
8284
                            <a href="'.$linkToCourseSession.'">'.get_lang('GoToCourseInsideSession').'</a>
8285
                            </div>';
8286
                    $htmlSession .= '<div style="margin-left:'.$marginShift.'px;">'.
8287
                        CourseManager::course_item_html($listParamsSession, true).'</div>';
8288
                }
8289
                $htmlCatSessions .= $htmlSession;
8290
            }
8291
            $htmlRes .= $htmlCourse.'<div style="display:none" id="course-'.$courseCode.'">'.$htmlCatSessions.'</div></div>';
8292
        }
8293
8294
        return $htmlRes;
8295
    }
8296
8297
    /**
8298
     * @param int $userId
8299
     * @param int $courseId
8300
     *
8301
     * @return array
8302
     */
8303 View Code Duplication
    public static function searchCourseInSessionsFromUser($userId, $courseId)
8304
    {
8305
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
8306
        $userId = (int) $userId;
8307
        $courseId = (int) $courseId;
8308
        if (empty($userId) || empty($courseId)) {
8309
            return [];
8310
        }
8311
8312
        $sql = "SELECT * FROM $table 
8313
                WHERE c_id = $courseId AND user_id = $userId";
8314
        $result = Database::query($sql);
8315
8316
        return Database::store_result($result, 'ASSOC');
8317
    }
8318
8319
    /**
8320
     * Subscribe and redirect to session after inscription
8321
     */
8322
    public static function redirectToSession()
8323
    {
8324
        $sessionId = ChamiloSession::read('session_redirect');
8325
        $onlyOneCourseSessionToRedirect = ChamiloSession::read('only_one_course_session_redirect');
8326
        if ($sessionId) {
8327
            $sessionInfo = api_get_session_info($sessionId);
8328
            if (!empty($sessionInfo)) {
8329
                $userId = api_get_user_id();
8330
                $response = self::isUserSubscribedAsStudent($sessionId, $userId);
8331
                if ($response) {
8332
                    $urlToRedirect = api_get_path(WEB_CODE_PATH) . 'session/index.php?session_id=' . $sessionId;
8333
                    if (!empty($onlyOneCourseSessionToRedirect)) {
8334
                        $urlToRedirect = api_get_path(WEB_PATH) . 'courses/' . $onlyOneCourseSessionToRedirect . '/index.php?id_session=' . $sessionId;
8335
                    }
8336
8337
                    header('Location: ' . $urlToRedirect);
8338
                    exit;
8339
                }
8340
            }
8341
        }
8342
    }
8343
8344
    /**
8345
     * @todo Add constatns in a DB table
8346
     */
8347
    static function getSessionChangeUserReasons()
8348
    {
8349
        return array(
8350
            self::SESSION_CHANGE_USER_REASON_SCHEDULE => get_lang(
8351
                'ScheduleChanged'
8352
            ),
8353
            self::SESSION_CHANGE_USER_REASON_CLASSROOM => get_lang(
8354
                'ClassRoomChanged'
8355
            ),
8356
            self::SESSION_CHANGE_USER_REASON_LOCATION => get_lang(
8357
                'LocationChanged'
8358
            ),
8359
            //self::SESSION_CHANGE_USER_REASON_ENROLLMENT_ANNULATION => get_lang('EnrollmentAnnulation'),
8360
        );
8361
    }
8362
8363
    /**
8364
     * Gets the reason name
8365
     * @param int $id reason id
8366
     * @return string
8367
     */
8368
    static function getSessionChangeUserReason($id)
8369
    {
8370
        $reasons = self::getSessionChangeUserReasons();
8371
8372
        return isset($reasons[$id]) ? $reasons[$id] : '';
8373
    }
8374
}
8375