Completed
Push — master ( f7178d...176486 )
by Julito
37:24
created

SessionManager::unsubscribe_user_from_session()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 57
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 37
nc 2
nop 2
dl 0
loc 57
rs 9.0309
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
5
use \ExtraField as ExtraFieldModel;
6
use Chamilo\CoreBundle\Entity\ExtraField;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, ExtraField.

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

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

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

// Bar.php
namespace OtherDir;

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

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

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

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

// Bar.php
namespace OtherDir;

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

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

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

    return array();
}

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

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

Loading history...
276
                        $user_id
277
                    );
278
                }
279
280
                return $session_id;
281
            }
282
        }
283
    }
284
285
    /**
286
     * @param string $name
287
     *
288
     * @return bool
289
     */
290 View Code Duplication
    public static function session_name_exists($name)
291
    {
292
        $name = Database::escape_string($name);
293
        $sql = "SELECT COUNT(*) as count FROM " . Database::get_main_table(TABLE_MAIN_SESSION) . "
294
                WHERE name = '$name'";
295
        $result = Database::fetch_array(Database::query($sql));
0 ignored issues
show
Bug introduced by
It seems like \Database::query($sql) can be null; however, fetch_array() does not accept null, maybe add an additional type check?

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
296
297
        return $result['count'] > 0;
298
    }
299
300
    /**
301
     * @param string $where_condition
302
     *
303
     * @return mixed
304
     */
305
    public static function get_count_admin($where_condition = '')
306
    {
307
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
308
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
309
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
310
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
311
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
312
313
        $where = 'WHERE 1=1 ';
314
        $user_id = api_get_user_id();
315
316
        $extraJoin = '';
317
318
        if (api_is_session_admin() &&
319
            api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
320
        ) {
321
            $where .= " AND (
322
                            s.session_admin_id = $user_id  OR
323
                            sru.user_id = '$user_id' AND
324
                            sru.relation_type = '" . SESSION_RELATION_TYPE_RRHH . "'
325
                            )
326
                      ";
327
328
            $extraJoin = " INNER JOIN $tbl_session_rel_user sru
329
                           ON sru.session_id = s.id ";
330
        }
331
332
        $today = api_get_utc_datetime();
333
        $today = api_strtotime($today, 'UTC');
0 ignored issues
show
Bug introduced by
It seems like $today defined by api_strtotime($today, 'UTC') on line 333 can also be of type null or object<DateTime>; however, api_strtotime() does only seem to accept string, maybe add an additional type check?

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

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

    return array();
}

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

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

Loading history...
334
        $today = date('Y-m-d', $today);
335
336
        if (!empty($where_condition)) {
337
            $where_condition = str_replace("(  session_active = ':'  )", '1=1', $where_condition);
338
339
            $where_condition = str_replace('category_name', 'sc.name', $where_condition);
340
            $where_condition = str_replace(
341
                array("AND session_active = '1'  )", " AND (  session_active = '1'  )"),
342
                array(') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 " )
343
                , $where_condition
344
            );
345
            $where_condition = str_replace(
346
                array("AND session_active = '0'  )", " AND (  session_active = '0'  )"),
347
                array(') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "),
348
                $where_condition
349
            );
350
        } else {
351
            $where_condition = " AND 1 = 1";
352
        }
353
354
        $courseCondition = null;
355
        if (strpos($where_condition, 'c.id')) {
356
            $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
357
            $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
358
            $courseCondition = " INNER JOIN $table course_rel_session
359
                                 ON (s.id = course_rel_session.session_id)
360
                                 INNER JOIN $tableCourse c
361
                                 ON (course_rel_session.c_id = c.id)
362
                                ";
363
        }
364
365
        $sql = "SELECT COUNT(id) as total_rows FROM (
366
                SELECT DISTINCT
367
                 IF (
368
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
369
                    (s.access_start_date IS NULL AND s.access_end_date  = IS NULL ) OR
370
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
371
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
372
				, 1, 0) as session_active,
373
                s.id
374
                FROM $tbl_session s
375
                LEFT JOIN $tbl_session_category sc
376
                ON s.session_category_id = sc.id
377
                INNER JOIN $tbl_user u
378
                ON s.id_coach = u.user_id
379
                $courseCondition
380
                $extraJoin
381
                $where $where_condition ) as session_table";
382
383
        if (api_is_multiple_url_enabled()) {
384
385
            $access_url_id = api_get_current_access_url_id();
386
            if ($access_url_id != -1) {
387
                $where.= " AND ar.access_url_id = $access_url_id ";
388
389
                $sql = "SELECT count(id) as total_rows FROM (
390
                SELECT DISTINCT
391
                  IF (
392
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
393
                    (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
394
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
395
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
396
				, 1, 0)
397
				as session_active,
398
				s.id
399
                FROM $tbl_session s
400
                    LEFT JOIN  $tbl_session_category sc
401
                    ON s.session_category_id = sc.id
402
                    INNER JOIN $tbl_user u ON s.id_coach = u.user_id
403
                    INNER JOIN $table_access_url_rel_session ar
404
                    ON ar.session_id = s.id
405
                    $courseCondition
406
                    $extraJoin
407
                $where $where_condition) as session_table";
408
            }
409
        }
410
411
        $result_rows = Database::query($sql);
412
        $row = Database::fetch_array($result_rows);
413
        $num = $row['total_rows'];
414
415
        return $num;
416
    }
417
418
    /**
419
     * Gets the admin session list callback of the session/session_list.php page
420
     * @param array $options order and limit keys
421
     * @param boolean $get_count Whether to get all the results or only the count
422
     * @return mixed Integer for number of rows, or array of results
423
     * @assert (array(),true) !== false
424
     */
425
    public static function get_sessions_admin($options = array(), $get_count = false)
426
    {
427
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
428
        $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
429
430
        $where = 'WHERE 1 = 1 ';
431
        $user_id = api_get_user_id();
432
433 View Code Duplication
        if (!api_is_platform_admin()) {
434
            if (api_is_session_admin() &&
435
                api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
436
            ) {
437
                $where .=" AND s.session_admin_id = $user_id ";
438
            }
439
        }
440
441
        if (!api_is_platform_admin() && api_is_teacher() &&
442
            api_get_setting('allow_teachers_to_create_sessions') == 'true'
443
        ) {
444
            $where .=" AND s.id_coach = $user_id ";
445
        }
446
447
        $extra_field = new ExtraFieldModel('session');
448
        $conditions = $extra_field->parseConditions($options);
449
        $inject_joins = $conditions['inject_joins'];
450
        $where .= $conditions['where'];
451
        $inject_where = $conditions['inject_where'];
452
        $inject_extra_fields = $conditions['inject_extra_fields'];
453
454
        $order = $conditions['order'];
455
        $limit = $conditions['limit'];
456
457
        $isMakingOrder = false;
458
459
        if ($get_count == true) {
460
            $select = " SELECT count(DISTINCT s.id) as total_rows";
461
        } else {
462
            $select =
463
                "SELECT DISTINCT 
464
                 s.name,
465
                 s.display_start_date, 
466
                 s.display_end_date, 
467
                 access_start_date, 
468
                 access_end_date, 
469
                 s.visibility, 
470
                 s.session_category_id, 
471
                 $inject_extra_fields 
472
                 s.id 
473
             ";
474
475
            $isMakingOrder = strpos($options['order'], 'category_name') === 0;
476
        }
477
478
        $isFilteringSessionCategory = strpos($where, 'category_name') !== false;
479
480
        if ($isMakingOrder || $isFilteringSessionCategory) {
481
            $inject_joins .= " LEFT JOIN $sessionCategoryTable sc ON s.session_category_id = sc.id ";
482
483
            if ($isFilteringSessionCategory) {
484
                $where = str_replace('category_name', 'sc.name', $where);
485
            }
486
487
            if ($isMakingOrder) {
488
                $order = str_replace('category_name', 'sc.name', $order);
489
            }
490
        }
491
492
        $query = "$select FROM $tbl_session s $inject_joins $where $inject_where";
493
494
        if (api_is_multiple_url_enabled()) {
495
            $table_access_url_rel_session= Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
496
            $access_url_id = api_get_current_access_url_id();
497
            if ($access_url_id != -1) {
498
                $where.= " AND ar.access_url_id = $access_url_id ";
499
                $query = "$select
500
                        FROM $tbl_session s $inject_joins
501
                        INNER JOIN $table_access_url_rel_session ar
502
                        ON (ar.session_id = s.id) $where";
503
            }
504
        }
505
506
        $query .= $order;
507
        $query .= $limit;
508
        $result = Database::query($query);
509
510
        $categories = self::get_all_session_category();
511
        $orderedCategories = array();
512
        if (!empty($categories)) {
513
            foreach ($categories as $category) {
514
                $orderedCategories[$category['id']] = $category['name'];
515
            }
516
        }
517
518
        $formatted_sessions = array();
519
520
        if (Database::num_rows($result)) {
521
            $sessions = Database::store_result($result, 'ASSOC');
522
            if ($get_count) {
523
                return $sessions[0]['total_rows'];
524
            }
525
526
            foreach ($sessions as $session) {
527
                $session_id = $session['id'];
528
                $session['name'] = Display::url($session['name'], "resume_session.php?id_session=".$session['id']);
529
530 View Code Duplication
                if (isset($session['session_active']) && $session['session_active'] == 1) {
531
                    $session['session_active'] = Display::return_icon('accept.png', get_lang('Active'), array(), ICON_SIZE_SMALL);
532
                } else {
533
                    $session['session_active'] = Display::return_icon('error.png', get_lang('Inactive'), array(), ICON_SIZE_SMALL);
534
                }
535
536
                $session = self::convert_dates_to_local($session, true);
537
538 View Code Duplication
                switch ($session['visibility']) {
539
                    case SESSION_VISIBLE_READ_ONLY: //1
540
                        $session['visibility'] = get_lang('ReadOnly');
541
                        break;
542
                    case SESSION_VISIBLE:           //2
543
                    case SESSION_AVAILABLE:         //4
544
                        $session['visibility'] = get_lang('Visible');
545
                        break;
546
                    case SESSION_INVISIBLE:         //3
547
                        $session['visibility'] = api_ucfirst(get_lang('Invisible'));
548
                        break;
549
                }
550
551
                // Cleaning double selects.
552 View Code Duplication
                foreach ($session as $key => &$value) {
0 ignored issues
show
Bug introduced by
The expression $session of type false|array<string,null|...d_date":"string|null"}> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

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

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

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

Loading history...
553
                    if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
554
                        $options = explode('::', $value);
555
                    }
556
                    $original_key = $key;
557
558
                    if (strpos($key, '_second') === false) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

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

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

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

could be turned into

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

This is much more concise to read.

Loading history...
559
                    } else {
560
                        $key = str_replace('_second', '', $key);
561
                    }
562
563
                    if (isset($options_by_double[$key])) {
564
                        if (isset($options[0])) {
565
                            if (isset($options_by_double[$key][$options[0]])) {
566
                                if (strpos($original_key, '_second') === false) {
567
                                    $value = $options_by_double[$key][$options[0]]['option_display_text'];
568
                                } else {
569
                                    $value = $options_by_double[$key][$options[1]]['option_display_text'];
570
                                }
571
                            }
572
                        }
573
                    }
574
                }
575
                $formatted_sessions[$session_id] = $session;
576
                $categoryName = isset($orderedCategories[$session['session_category_id']]) ? $orderedCategories[$session['session_category_id']] : '';
577
                $formatted_sessions[$session_id]['category_name'] = $categoryName;
578
            }
579
        }
580
        return $formatted_sessions;
581
    }
582
583
    /**
584
     *  Get total of records for progress of learning paths in the given session
585
     *  @param int session id
586
     *  @return int
587
     */
588
    public static function get_count_session_lp_progress($sessionId = 0)
589
    {
590
        $tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
591
        $tbl_lp_view = Database::get_course_table(TABLE_LP_VIEW);
592
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
593
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
594
595
        $sessionId = intval($sessionId);
596
597
        $sql = "SELECT  count(*) as total_rows
598
                FROM $tbl_lp_view v
599
                INNER JOIN $tbl_lp l ON l.id = v.lp_id
600
                INNER JOIN $tbl_user u ON u.user_id = v.user_id
601
                INNER JOIN $tbl_course c
602
                WHERE v.session_id = " . $sessionId;
603
        $result_rows = Database::query($sql);
604
        $row = Database::fetch_array($result_rows);
605
        $num = $row['total_rows'];
606
607
        return $num;
608
    }
609
610
    /**
611
     * Gets the progress of learning paths in the given session
612
     * @param int   $sessionId
613
     * @param int $courseId
614
     * @param string $date_from
615
     * @param string $date_to
616
     * @param array options order and limit keys
617
     * @return array table with user name, lp name, progress
618
     */
619
    public static function get_session_lp_progress($sessionId = 0, $courseId = 0, $date_from, $date_to, $options)
620
    {
621
        //escaping vars
622
        $sessionId = $sessionId == 'T' ? 'T' : intval($sessionId);
623
        $courseId = intval($courseId);
624
        $date_from = Database :: escape_string($date_from);
625
        $date_to = Database :: escape_string($date_to);
626
627
        //tables
628
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
629
        $user = Database::get_main_table(TABLE_MAIN_USER);
630
        $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
631
632
        $course = api_get_course_info_by_id($courseId);
633
634
        //getting all the students of the course
635
        //we are not using this because it only returns user ids
636
        /* if (empty($sessionId)
637
          {
638
          // Registered students in a course outside session.
639
          $users = CourseManager :: get_student_list_from_course_code($course_code);
640
          } else {
641
          // Registered students in session.
642
          $users = CourseManager :: get_student_list_from_course_code($course_code, true, $sessionId);
643
          } */
644
645
        $sessionCond = 'and session_id = %s';
646
        if ($sessionId == 'T') {
647
            $sessionCond = "";
648
        }
649
650
        $where = " WHERE c_id = '%s' AND s.status <> 2 $sessionCond";
651
652
        $limit = null;
653
        if (!empty($options['limit'])) {
654
            $limit = " LIMIT " . $options['limit'];
655
        }
656
657
        if (!empty($options['where'])) {
658
            $where .= ' '.$options['where'];
659
        }
660
661
        $order = null;
662
        if (!empty($options['order'])) {
663
            $order = " ORDER BY " . $options['order'];
664
        }
665
666
        $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
667
                FROM $session_course_user s
668
                INNER JOIN $user u ON u.user_id = s.user_id
669
                $where
670
                $order
671
                $limit";
672
673
        $sql_query = sprintf($sql, Database::escape_string($course['real_id']), $sessionId);
674
675
        $rs = Database::query($sql_query);
676
        while ($user = Database::fetch_array($rs)) {
677
            $users[$user['user_id']] = $user;
678
        }
679
680
        //Get lessons
681
        $lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
682
683
        $table = array();
684
        foreach ($users as $user) {
685
            $data = array(
686
                'lastname' => $user[1],
687
                'firstname' => $user[2],
688
                'username' => $user[3],
689
            );
690
691
            $sessionCond = 'AND v.session_id = %d';
692
            if ($sessionId == 'T') {
693
                $sessionCond = "";
694
            }
695
696
            //Get lessons progress by user
697
            $sql = "SELECT v.lp_id as id, v.progress
698
                    FROM  $tbl_course_lp_view v
699
                    WHERE v.c_id = %d
700
                    AND v.user_id = %d
701
            $sessionCond";
702
703
            $sql_query = sprintf($sql,
704
                intval($courseId),
705
                intval($user['user_id']),
706
                $sessionId
707
            );
708
709
            $result = Database::query($sql_query);
710
711
            $user_lessons = array();
712
            while ($row = Database::fetch_array($result)) {
713
                $user_lessons[$row['id']] = $row;
714
            }
715
716
            //Match course lessons with user progress
717
            $progress = 0;
718
            $count = 0;
719
            foreach ($lessons as $lesson) {
720
                $data[$lesson['id']] = (!empty($user_lessons[$lesson['id']]['progress'])) ? $user_lessons[$lesson['id']]['progress'] : 0;
721
                $progress += $data[$lesson['id']];
722
                $data[$lesson['id']] = $data[$lesson['id']] . '%';
723
                $count++;
724
            }
725
            if ($count == 0) {
726
                $data['total'] = 0;
727
            } else {
728
                $data['total'] = round($progress / $count, 2) . '%';
729
            }
730
            $table[] = $data;
731
        }
732
733
        return $table;
734
    }
735
736
    /**
737
     * Gets the survey answers
738
     * @param int   $sessionId
739
     * @param int   $courseId
740
     * @param int   $surveyId
741
     * @param array options order and limit keys
742
     * @todo fix the query
743
     * @return array table with user name, lp name, progress
744
     */
745
    public static function get_survey_overview($sessionId = 0, $courseId = 0, $surveyId = 0, $date_from, $date_to, $options)
746
    {
747
        //escaping vars
748
        $sessionId = intval($sessionId);
749
        $courseId = intval($courseId);
750
        $surveyId = intval($surveyId);
751
        $date_from = Database::escape_string($date_from);
752
        $date_to = Database::escape_string($date_to);
753
754
        //tables
755
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
756
        $user = Database::get_main_table(TABLE_MAIN_USER);
757
        $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
758
        $c_survey = Database::get_course_table(TABLE_SURVEY);
759
        $c_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
760
        $c_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
761
        $c_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
762
763
        $course = api_get_course_info_by_id($courseId);
764
765
        $where = " WHERE c_id = '%s' AND s.status <> 2 AND session_id = %s";
766
767
        $limit = null;
768
        if (!empty($options['limit'])) {
769
            $limit = " LIMIT " . $options['limit'];
770
        }
771
772
        if (!empty($options['where'])) {
773
            $where .= ' '.$options['where'];
774
        }
775
776
        $order = null;
777
        if (!empty($options['order'])) {
778
            $order = " ORDER BY " . $options['order'];
779
        }
780
781
        $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
782
                FROM $session_course_user s
783
                INNER JOIN $user u ON u.user_id = s.user_id
784
                $where $order $limit";
785
786
        $sql_query = sprintf($sql, intval($course['real_id']), $sessionId);
787
        $rs = Database::query($sql_query);
788
        while ($user = Database::fetch_array($rs)) {
789
            $users[$user['user_id']] = $user;
790
        }
791
792
        //Get survey questions
793
        $questions = SurveyManager::get_questions($surveyId, $courseId);
794
795
        //Survey is anonymous?
796
        $result = Database::query(sprintf("SELECT anonymous FROM $c_survey WHERE survey_id = %d", $surveyId));
797
        $row = Database::fetch_array($result);
798
        $anonymous = ($row['anonymous'] == 1) ? true : false;
799
800
        $table = array();
801
        foreach ($users as $user) {
802
            $data = array(
803
                'lastname' => ($anonymous ? '***' : $user[1]),
804
                'firstname' => ($anonymous ? '***' : $user[2]),
805
                'username' => ($anonymous ? '***' : $user[3]),
806
            );
807
808
            //Get questions by user
809
            $sql = "SELECT sa.question_id, sa.option_id, sqo.option_text, sq.type
810
                    FROM $c_survey_answer sa
811
                    INNER JOIN $c_survey_question sq
812
                    ON sq.question_id = sa.question_id
813
                    LEFT JOIN $c_survey_question_option sqo
814
                    ON
815
                      sqo.c_id = sa.c_id AND
816
                      sqo.question_id = sq.question_id AND
817
                      sqo.question_option_id = sa.option_id AND
818
                      sqo.survey_id = sq.survey_id
819
                    WHERE
820
                      sa.survey_id = %d AND
821
                      sa.c_id = %d AND
822
                      sa.user = %d
823
            "; //. $where_survey;
824
            $sql_query = sprintf($sql, $surveyId, $courseId, $user['user_id']);
825
826
            $result = Database::query($sql_query);
827
828
            $user_questions = array();
829
            while ($row = Database::fetch_array($result)) {
830
                $user_questions[$row['question_id']] = $row;
831
            }
832
833
            //Match course lessons with user progress
834
            foreach ($questions as $question_id => $question) {
835
                $option_text = 'option_text';
836
                if ($user_questions[$question_id]['type'] == 'open') {
837
                    $option_text = 'option_id';
838
                }
839
                $data[$question_id] = $user_questions[$question_id][$option_text];
840
            }
841
842
            $table[] = $data;
843
        }
844
        return $table;
845
    }
846
847
    /**
848
     * Gets the progress of the given session
849
     * @param int   $sessionId
850
     * @param int   $courseId
851
     * @param array options order and limit keys
852
     *
853
     * @return array table with user name, lp name, progress
854
     */
855
    public static function get_session_progress($sessionId, $courseId, $date_from, $date_to, $options)
856
    {
857
        $sessionId = intval($sessionId);
858
859
        $getAllSessions = false;
860
        if (empty($sessionId)) {
861
            $sessionId = 0;
862
            $getAllSessions = true;
863
        }
864
865
        //tables
866
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
867
        $user = Database::get_main_table(TABLE_MAIN_USER);
868
        $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
869
        $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
870
        $tbl_course_lp = Database::get_course_table(TABLE_LP_MAIN);
871
        $wiki = Database::get_course_table(TABLE_WIKI);
872
        $table_stats_default = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
873
        $table_stats_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
874
875
        $course = api_get_course_info_by_id($courseId);
876
        $where = " WHERE c_id = '%s' AND s.status <> 2 ";
877
878
        $limit = null;
879
        if (!empty($options['limit'])) {
880
            $limit = " LIMIT " . $options['limit'];
881
        }
882
883
        if (!empty($options['where'])) {
884
            $where .= ' '.$options['where'];
885
        }
886
887
        $order = null;
888
        if (!empty($options['order'])) {
889
            $order = " ORDER BY " . $options['order'];
890
        }
891
892
        //TODO, fix create report without session
893
        $queryVariables = array($course['real_id']);
894
        if (!empty($sessionId)) {
895
            $where .= ' AND session_id = %s';
896
            $queryVariables[] = $sessionId;
897
            $sql = "SELECT
898
                        u.user_id, u.lastname, u.firstname, u.username,
899
                        u.email, s.c_id, s.session_id
900
                    FROM $session_course_user s
901
                    INNER JOIN $user u
902
                    ON u.user_id = s.user_id
903
                    $where $order $limit";
904
        } else {
905
            $sql = "SELECT
906
                        u.user_id, u.lastname, u.firstname, u.username,
907
                        u.email, s.c_id, s.session_id
908
                    FROM $session_course_user s
909
                    INNER JOIN $user u ON u.user_id = s.user_id
910
                    $where $order $limit";
911
        }
912
913
        $sql_query = vsprintf($sql, $queryVariables);
914
        $rs = Database::query($sql_query);
915
        while ($user = Database::fetch_array($rs)) {
916
            $users[$user['user_id']] = $user;
917
        }
918
919
        /**
920
         *  Lessons
921
         */
922
        $sql = "SELECT * FROM $tbl_course_lp WHERE c_id = %s ";  //AND session_id = %s
923
        $sql_query = sprintf($sql, $course['real_id']);
924
        $result = Database::query($sql_query);
925
        $arrLesson = array(array());
926 View Code Duplication
        while ($row = Database::fetch_array($result)) {
927
            if (empty($arrLesson[$row['session_id']]['lessons_total'])) {
928
                $arrLesson[$row['session_id']]['lessons_total'] = 1;
929
            } else {
930
                $arrLesson[$row['session_id']]['lessons_total'] ++;
931
            }
932
        }
933
934
        /**
935
         *  Exercises
936
         */
937
        $exercises = ExerciseLib::get_all_exercises($course, $sessionId, false, '', $getAllSessions);
938
        $exercises_total = count($exercises);
939
940
        /**
941
         *  Assignments
942
         */
943
        //total
944
        $params = [$course['real_id']];
945
        if ($getAllSessions) {
946
            $sql = "SELECT count(w.id) as count
947
                    FROM $workTable w
948
                    LEFT JOIN $workTableAssignment a
949
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
950
                    WHERE w.c_id = %s
951
                    AND parent_id = 0
952
                    AND active IN (1, 0)";
953
        } else {
954
            $sql = "SELECT count(w.id) as count
955
                    FROM $workTable w
956
                    LEFT JOIN $workTableAssignment a
957
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
958
                    WHERE w.c_id = %s
959
                    AND parent_id = 0
960
                    AND active IN (1, 0)";
961
962
            if (empty($sessionId)) {
963
                $sql .= ' AND w.session_id = NULL ';
964
            } else {
965
                $sql .= ' AND w.session_id = %s ';
966
                $params[] = $sessionId;
967
            }
968
        }
969
970
        $sql_query = vsprintf($sql, $params);
971
        $result = Database::query($sql_query);
972
        $row = Database::fetch_array($result);
973
        $assignments_total = $row['count'];
974
975
        /**
976
         * Wiki
977
         */
978
        if ($getAllSessions) {
979
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
980
                    WHERE c_id = %s";
981
        } else {
982
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
983
                    WHERE c_id = %s and session_id = %s";
984
        }
985
        $sql_query = sprintf($sql, $course['real_id'], $sessionId);
986
        $result = Database::query($sql_query);
987
        $row = Database::fetch_array($result);
988
        $wiki_total = $row['count'];
989
990
        /**
991
         * Surveys
992
         */
993
        $survey_user_list = array();
994
        $survey_list = SurveyManager::get_surveys($course['code'], $sessionId);
995
996
        $surveys_total = count($survey_list);
997 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...
998
            $user_list = SurveyManager::get_people_who_filled_survey(
999
                $survey['survey_id'],
1000
                false,
1001
                $course['real_id']
1002
            );
1003
            foreach ($user_list as $user_id) {
1004
                isset($survey_user_list[$user_id]) ? $survey_user_list[$user_id] ++ : $survey_user_list[$user_id] = 1;
1005
            }
1006
        }
1007
1008
        /**
1009
         * Forums
1010
         */
1011
        $forums_total = CourseManager::getCountForum(
1012
            $course['real_id'],
1013
            $sessionId,
1014
            $getAllSessions
1015
        );
1016
1017
        //process table info
1018
        foreach ($users as $user) {
1019
            //Course description
1020
            $sql = "SELECT count(*) as count
1021
                    FROM $table_stats_access
1022
                    WHERE access_tool = 'course_description'
1023
                    AND c_id = '%s'
1024
                    AND access_session_id = %s
1025
                    AND access_user_id = %s ";
1026
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1027
1028
            $result = Database::query($sql_query);
1029
            $row = Database::fetch_array($result);
1030
            $course_description_progress = ($row['count'] > 0) ? 100 : 0;
1031
1032
            if (!empty($arrLesson[$user['id_session']]['lessons_total'])) {
1033
                $lessons_total = $arrLesson[$user['id_session']]['lessons_total'];
1034
            } else {
1035
                $lessons_total = !empty($arrLesson[0]['lessons_total']) ? $arrLesson[0]['lessons_total'] : 0;
1036
            }
1037
1038
            //Lessons
1039
            //TODO: Lessons done and left is calculated by progress per item in lesson, maybe we should calculate it only per completed lesson?
1040
            $lessons_progress = Tracking::get_avg_student_progress(
1041
                $user['user_id'],
1042
                $course['code'],
1043
                array(),
1044
                $user['id_session']
1045
            );
1046
            $lessons_done = ($lessons_progress * $lessons_total) / 100;
1047
            $lessons_left = $lessons_total - $lessons_done;
1048
1049
            //Exercises
1050
            $exercises_progress = str_replace('%', '', Tracking::get_exercise_student_progress($exercises, $user['user_id'], $course['real_id'], $user['id_session']));
1051
            $exercises_done = round(($exercises_progress * $exercises_total) / 100);
1052
            $exercises_left = $exercises_total - $exercises_done;
1053
1054
            //Assignments
1055
            $assignments_done = Tracking::count_student_assignments($user['user_id'], $course['code'], $user['id_session']);
1056
            $assignments_left = $assignments_total - $assignments_done;
1057
            if (!empty($assignments_total)) {
1058
                $assignments_progress = round((( $assignments_done * 100 ) / $assignments_total), 2);
1059
            } else {
1060
                $assignments_progress = 0;
1061
            }
1062
1063
            //Wiki
1064
            //total revisions per user
1065
            $sql = "SELECT count(*) as count
1066
                    FROM $wiki
1067
                    WHERE c_id = %s and session_id = %s and user_id = %s";
1068
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1069
            $result = Database::query($sql_query);
1070
            $row = Database::fetch_array($result);
1071
            $wiki_revisions = $row['count'];
1072
            //count visited wiki pages
1073
            $sql = "SELECT count(distinct default_value) as count
1074
                    FROM $table_stats_default
1075
                    WHERE
1076
                        default_user_id = %s AND
1077
                        default_event_type = 'wiki_page_view' AND
1078
                        default_value_type = 'wiki_page_id' AND
1079
                        c_id = %s
1080
                    ";
1081
            $sql_query = sprintf($sql, $user['user_id'], $course['real_id']);
1082
            $result = Database::query($sql_query);
1083
            $row = Database::fetch_array($result);
1084
1085
            $wiki_read = $row['count'];
1086
            $wiki_unread = $wiki_total - $wiki_read;
1087
            if (!empty($wiki_total)) {
1088
                $wiki_progress = round((( $wiki_read * 100 ) / $wiki_total), 2);
1089
            } else {
1090
                $wiki_progress = 0;
1091
            }
1092
1093
            //Surveys
1094
            $surveys_done = (isset($survey_user_list[$user['user_id']]) ? $survey_user_list[$user['user_id']] : 0);
1095
            $surveys_left = $surveys_total - $surveys_done;
1096
            if (!empty($surveys_total)) {
1097
                $surveys_progress = round((( $surveys_done * 100 ) / $surveys_total), 2);
1098
            } else {
1099
                $surveys_progress = 0;
1100
            }
1101
1102
            //Forums
1103
            $forums_done = CourseManager::getCountForumPerUser(
1104
                $user['user_id'],
1105
                $course['real_id'],
1106
                $user['id_session']
1107
            );
1108
            $forums_left = $forums_total - $forums_done;
1109
            if (!empty($forums_total)) {
1110
                $forums_progress = round((( $forums_done * 100 ) / $forums_total), 2);
1111
            } else {
1112
                $forums_progress = 0;
1113
            }
1114
1115
            //Overall Total
1116
            $overall_total = ($course_description_progress + $exercises_progress + $forums_progress + $assignments_progress + $wiki_progress + $surveys_progress) / 6;
1117
1118
            $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>';
1119
            $linkForum = '<a href="' . api_get_path(WEB_CODE_PATH) . 'forum/index.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1120
            $linkWork = '<a href="' . api_get_path(WEB_CODE_PATH) . 'work/work.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1121
            $linkWiki = '<a href="' . api_get_path(WEB_CODE_PATH) . 'wiki/index.php?cidReq=' . $course['code'] . '&session_id=' . $user['id_session'] . '&action=statistics"> %s </a>';
1122
            $linkSurvey = '<a href="' . api_get_path(WEB_CODE_PATH) . 'survey/survey_list.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1123
1124
            $table[] = array(
1125
                'lastname' => $user[1],
1126
                'firstname' => $user[2],
1127
                'username' => $user[3],
1128
                #'profile'   => '',
1129
                'total' => round($overall_total, 2) . '%',
1130
                'courses' => sprintf($link, $course_description_progress . '%'),
1131
                'lessons' => sprintf($link, $lessons_progress . '%'),
1132
                'exercises' => sprintf($link, $exercises_progress . '%'),
1133
                'forums' => sprintf($link, $forums_progress . '%'),
1134
                'homeworks' => sprintf($link, $assignments_progress . '%'),
1135
                'wikis' => sprintf($link, $wiki_progress . '%'),
1136
                'surveys' => sprintf($link, $surveys_progress . '%'),
1137
                //course description
1138
                'course_description_progress' => $course_description_progress . '%',
1139
                //lessons
1140
                'lessons_total' => sprintf($link, $lessons_total),
1141
                'lessons_done' => sprintf($link, $lessons_done),
1142
                'lessons_left' => sprintf($link, $lessons_left),
1143
                'lessons_progress' => sprintf($link, $lessons_progress . '%'),
1144
                //exercises
1145
                'exercises_total' => sprintf($link, $exercises_total),
1146
                'exercises_done' => sprintf($link, $exercises_done),
1147
                'exercises_left' => sprintf($link, $exercises_left),
1148
                'exercises_progress' => sprintf($link, $exercises_progress . '%'),
1149
                //forums
1150
                'forums_total' => sprintf($linkForum, $forums_total),
1151
                'forums_done' => sprintf($linkForum, $forums_done),
1152
                'forums_left' => sprintf($linkForum, $forums_left),
1153
                'forums_progress' => sprintf($linkForum, $forums_progress . '%'),
1154
                //assignments
1155
                'assignments_total' => sprintf($linkWork, $assignments_total),
1156
                'assignments_done' => sprintf($linkWork, $assignments_done),
1157
                'assignments_left' => sprintf($linkWork, $assignments_left),
1158
                'assignments_progress' => sprintf($linkWork, $assignments_progress . '%'),
1159
                //wiki
1160
                'wiki_total' => sprintf($linkWiki, $wiki_total),
1161
                'wiki_revisions' => sprintf($linkWiki, $wiki_revisions),
1162
                'wiki_read' => sprintf($linkWiki, $wiki_read),
1163
                'wiki_unread' => sprintf($linkWiki, $wiki_unread),
1164
                'wiki_progress' => sprintf($linkWiki, $wiki_progress . '%'),
1165
                //survey
1166
                'surveys_total' => sprintf($linkSurvey, $surveys_total),
1167
                'surveys_done' => sprintf($linkSurvey, $surveys_done),
1168
                'surveys_left' => sprintf($linkSurvey, $surveys_left),
1169
                'surveys_progress' => sprintf($linkSurvey, $surveys_progress . '%'),
1170
            );
1171
        }
1172
1173
        return $table;
1174
    }
1175
1176
    /**
1177
     * @return int
1178
     */
1179
    public static function get_number_of_tracking_access_overview()
1180
    {
1181
        // database table definition
1182
        $track_e_course_access = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1183
1184
        return Database::count_rows($track_e_course_access);
0 ignored issues
show
Deprecated Code introduced by
The method Database::count_rows() has been deprecated.

This method has been deprecated.

Loading history...
1185
    }
1186
1187
    /**
1188
     * Get the ip, total of clicks, login date and time logged in for all user, in one session
1189
     * @todo track_e_course_access table should have ip so we dont have to look for it in track_e_login
1190
     *
1191
     * @author César Perales <[email protected]>, Beeznest Team
1192
     * @version 1.9.6
1193
     */
1194
    public static function get_user_data_access_tracking_overview(
1195
        $sessionId,
1196
        $courseId,
1197
        $studentId = 0,
1198
        $profile = '',
1199
        $date_from = '',
1200
        $date_to = '',
1201
        $options
1202
    ) {
1203
        //escaping variables
1204
        $sessionId = intval($sessionId);
1205
        $courseId = intval($courseId);
1206
        $studentId = intval($studentId);
1207
        $profile = intval($profile);
1208
        $date_from = Database::escape_string($date_from);
1209
        $date_to = Database::escape_string($date_to);
1210
1211
        // database table definition
1212
        $user = Database :: get_main_table(TABLE_MAIN_USER);
1213
        $course = Database :: get_main_table(TABLE_MAIN_COURSE);
1214
        $track_e_login = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
1215
        $track_e_course_access = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1216
        $sessionTable = Database :: get_main_table(TABLE_MAIN_SESSION);
1217
1218
        global $export_csv;
1219
        if ($export_csv) {
1220
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
1221
        } else {
1222
            $is_western_name_order = api_is_western_name_order();
1223
        }
1224
1225
        $where = null;
1226
        if (isset($sessionId) && !empty($sessionId)) {
1227
            $where = sprintf(" WHERE a.session_id = %d", $sessionId);
1228
        }
1229
        if (isset($courseId) && !empty($courseId)) {
1230
            $where .= sprintf(" AND c.id = %d", $courseId);
1231
        }
1232
        if (isset($studentId) && !empty($studentId)) {
1233
            $where .= sprintf(" AND u.user_id = %d", $studentId);
1234
        }
1235
        if (isset($profile) && !empty($profile)) {
1236
            $where .= sprintf(" AND u.status = %d", $profile);
1237
        }
1238
        if (!empty($date_to) && !empty($date_from)) {
1239
            $where .= sprintf(
1240
                " AND a.login_course_date >= '%s 00:00:00'
1241
                 AND a.login_course_date <= '%s 23:59:59'",
1242
                $date_from,
1243
                $date_to
1244
            );
1245
        }
1246
1247
        $limit = null;
1248
        if (!empty($options['limit'])) {
1249
            $limit = " LIMIT " . $options['limit'];
1250
        }
1251
1252
        if (!empty($options['where'])) {
1253
            $where .= ' '.$options['where'];
1254
        }
1255
1256
        $order = null;
1257
        if (!empty($options['order'])) {
1258
            $order = " ORDER BY " . $options['order'];
1259
        }
1260
1261
        //TODO add course name
1262
        $sql = "SELECT
1263
                a.login_course_date ,
1264
                u.username ,
1265
                " . ($is_western_name_order ? "
1266
                    u.firstname,
1267
                    u.lastname,
1268
                    " : "
1269
                    u.lastname,
1270
                    u.firstname,
1271
                ") . "
1272
                a.logout_course_date,
1273
                a.counter,
1274
                c.title,
1275
                c.code,
1276
                u.user_id,
1277
                a.session_id
1278
            FROM $track_e_course_access a
1279
            INNER JOIN $user u ON a.user_id = u.user_id
1280
            INNER JOIN $course c ON a.c_id = c.id
1281
            $where $order $limit";
1282
        $result = Database::query(sprintf($sql, $sessionId, $courseId));
1283
1284
        $data = array();
1285
        while ($user = Database::fetch_assoc($result)) {
1286
            $data[] = $user;
1287
        }
1288
1289
        //foreach
1290
        foreach ($data as $key => $info) {
1291
            $sql = "SELECT
1292
                    name
1293
                    FROM $sessionTable
1294
                    WHERE
1295
                    id = {$info['session_id']}";
1296
            $result = Database::query($sql);
1297
            $session = Database::fetch_assoc($result);
1298
1299
            // building array to display
1300
            $return[] = array(
1301
                'user_id' => $info['user_id'],
1302
                'logindate' => $info['login_course_date'],
1303
                'username' => $info['username'],
1304
                'firstname' => $info['firstname'],
1305
                'lastname' => $info['lastname'],
1306
                'clicks' => $info['counter'], //+ $clicks[$info['user_id']],
1307
                'ip' => '',
1308
                'timeLoggedIn' => gmdate("H:i:s", strtotime($info['logout_course_date']) - strtotime($info['login_course_date'])),
1309
                'session' => $session['name']
1310
            );
1311
        }
1312
1313
        foreach ($return as $key => $info) {
1314
            //Search for ip, we do less querys if we iterate the final array
1315
            $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
1316
            $result = Database::query($sql);
1317
            $ip = Database::fetch_assoc($result);
1318
            //if no ip founded, we search the closest higher ip
1319
            if (empty($ip['user_ip'])) {
1320
                $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
1321
                $result = Database::query($sql);
1322
                $ip = Database::fetch_assoc($result);
1323
            }
1324
            #add ip to final array
1325
            $return[$key]['ip'] = $ip['user_ip'];
1326
        }
1327
1328
        return $return;
1329
    }
1330
1331
    /**
1332
     * Creates a new course code based in given code
1333
     *
1334
     * @param string	$session_name
1335
     * <code>
1336
     * $wanted_code = 'curse' if there are in the DB codes like curse1 curse2 the function will return: course3
1337
     * if the course code doest not exist in the DB the same course code will be returned
1338
     * </code>
1339
     * @return string	wanted unused code
1340
     */
1341 View Code Duplication
    public static function generateNextSessionName($session_name)
1342
    {
1343
        $session_name_ok = !self::session_name_exists($session_name);
1344
        if (!$session_name_ok) {
1345
            $table = Database::get_main_table(TABLE_MAIN_SESSION);
1346
            $session_name = Database::escape_string($session_name);
1347
            $sql = "SELECT count(*) as count FROM $table
1348
                    WHERE name LIKE '$session_name%'";
1349
            $result = Database::query($sql);
1350
            if (Database::num_rows($result) > 0) {
1351
                $row = Database::fetch_array($result);
1352
                $count = $row['count'] + 1;
1353
                $session_name = $session_name . '_' . $count;
1354
                $result = self::session_name_exists($session_name);
1355
                if (!$result) {
1356
                    return $session_name;
1357
                }
1358
            }
1359
            return false;
1360
        }
1361
1362
        return $session_name;
1363
    }
1364
1365
    /**
1366
     * Edit a session
1367
     * @author Carlos Vargas from existing code
1368
     * @param integer   $id Session primary key
1369
     * @param string    $name
1370
     * @param string    $startDate
1371
     * @param string    $endDate
1372
     * @param string    $displayStartDate
1373
     * @param string    $displayEndDate
1374
     * @param string    $coachStartDate
1375
     * @param string    $coachEndDate
1376
     * @param integer   $coachId
1377
     * @param integer   $sessionCategoryId
1378
     * @param int       $visibility
1379
     * @param string    $description
1380
     * @param int       $showDescription
1381
     * @param int       $duration
1382
     * @param array     $extraFields
1383
     * @param int       $sessionAdminId
1384
     * @param boolean $sendSubscriptionNotification Optional.
1385
     *          Whether send a mail notification to users being subscribed
1386
     * @return mixed
1387
     */
1388
    public static function edit_session(
1389
        $id,
1390
        $name,
1391
        $startDate,
1392
        $endDate,
1393
        $displayStartDate,
1394
        $displayEndDate,
1395
        $coachStartDate,
1396
        $coachEndDate,
1397
        $coachId,
1398
        $sessionCategoryId,
1399
        $visibility,
1400
        $description = null,
1401
        $showDescription = 0,
1402
        $duration = null,
1403
        $extraFields = array(),
1404
        $sessionAdminId = 0,
1405
        $sendSubscriptionNotification = false
1406
    ) {
1407
        $coachId = intval($coachId);
1408
        $sessionCategoryId = intval($sessionCategoryId);
1409
        $visibility = intval($visibility);
1410
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1411
1412
        if (empty($name)) {
1413
            Display::addFlash(
1414
                Display::return_message(get_lang('SessionNameIsRequired'), 'warning')
1415
            );
1416
1417
            return false;
1418
        } elseif (empty($coachId)) {
1419
            Display::addFlash(
1420
                Display::return_message(get_lang('CoachIsRequired'), 'warning')
1421
            );
1422
1423
            return false;
1424
        } elseif (!empty($startDate) && !api_is_valid_date($startDate, 'Y-m-d H:i') && !api_is_valid_date($startDate, 'Y-m-d H:i:s')) {
1425
            Display::addFlash(
1426
                Display::return_message(get_lang('InvalidStartDate'), 'warning')
1427
            );
1428
1429
            return false;
1430
        } elseif (!empty($endDate) && !api_is_valid_date($endDate, 'Y-m-d H:i') && !api_is_valid_date($endDate, 'Y-m-d H:i:s')) {
1431
            Display::addFlash(
1432
                Display::return_message(get_lang('InvalidEndDate'), 'warning')
1433
            );
1434
1435
            return false;
1436
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
1437
            Display::addFlash(
1438
                Display::return_message(get_lang('StartDateShouldBeBeforeEndDate'), 'warning')
1439
            );
1440
1441
            return false;
1442
        } else {
1443
            $sessionInfo = self::get_session_by_name($name);
1444
            $exists = false;
1445
1446
            if (!empty($sessionInfo)) {
1447
                if ($sessionInfo['id'] != $id) {
1448
                    $exists = true;
1449
                }
1450
            }
1451
1452
            if ($exists) {
1453
                Display::addFlash(
1454
                    Display::return_message(get_lang('SessionNameAlreadyExists'), 'warning')
1455
                );
1456
1457
                return false;
1458
            } else {
1459
                $values = [
1460
                    'name' => $name,
1461
                    'duration' => $duration,
1462
                    'id_coach' => $coachId,
1463
                    'description'=> $description,
1464
                    'show_description' => intval($showDescription),
1465
                    'visibility' => $visibility,
1466
                    'send_subscription_notification' => $sendSubscriptionNotification,
1467
                    'access_start_date' => null,
1468
                    'access_end_date' => null,
1469
                    'display_start_date' => null,
1470
                    'display_end_date' => null,
1471
                    'coach_access_start_date' => null,
1472
                    'coach_access_end_date' => null
1473
                ];
1474
1475
                if (!empty($sessionAdminId)) {
1476
                    $values['session_admin_id'] = $sessionAdminId;
1477
                }
1478
1479
                if (!empty($startDate)) {
1480
                    $values['access_start_date'] = api_get_utc_datetime($startDate);
1481
                }
1482
1483
                if (!empty($endDate)) {
1484
                    $values['access_end_date'] = api_get_utc_datetime($endDate);
1485
                }
1486
1487
                if (!empty($displayStartDate)) {
1488
                    $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
1489
                }
1490
1491
                if (!empty($displayEndDate)) {
1492
                    $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
1493
                }
1494
1495
                if (!empty($coachStartDate)) {
1496
                    $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
1497
                }
1498
                if (!empty($coachEndDate)) {
1499
                    $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
1500
                }
1501
1502
                if (!empty($sessionCategoryId)) {
1503
                    $values['session_category_id'] = $sessionCategoryId;
1504
                } else {
1505
                    $values['session_category_id'] = null;
1506
                }
1507
1508
                Database::update(
1509
                    $tbl_session,
1510
                    $values,
1511
                    array('id = ?' => $id)
1512
                );
1513
1514
                if (!empty($extraFields)) {
1515
                    $extraFields['item_id'] = $id;
1516
                    $sessionFieldValue = new ExtraFieldValue('session');
1517
                    $sessionFieldValue->saveFieldValues($extraFields);
1518
                }
1519
1520
                return $id;
1521
            }
1522
        }
1523
    }
1524
1525
    /**
1526
     * Delete session
1527
     * @author Carlos Vargas  from existing code
1528
     * @param	array	$id_checked an array to delete sessions
1529
     * @param   boolean  $from_ws optional, true if the function is called
1530
     * by a webservice, false otherwise.
1531
     * @return	void	Nothing, or false on error
1532
     * */
1533
    public static function delete($id_checked, $from_ws = false)
1534
    {
1535
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1536
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1537
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1538
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1539
        $tbl_url_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
1540
        $tbl_item_properties = Database::get_course_table(TABLE_ITEM_PROPERTY);
1541
        $tbl_student_publication = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1542
        $tbl_student_publication_assignment = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1543
        $ticket = Database::get_main_table(TABLE_TICKET_TICKET);
1544
        $em = Database::getManager();
1545
1546
        $userId = api_get_user_id();
1547
1548
        if (is_array($id_checked)) {
1549
            foreach ($id_checked as $sessionId) {
1550
                self::delete($sessionId);
1551
            }
1552
        } else {
1553
            $id_checked = intval($id_checked);
1554
        }
1555
1556
        if (SessionManager::allowed($id_checked) && !$from_ws) {
0 ignored issues
show
Bug introduced by
It seems like $id_checked defined by parameter $id_checked on line 1533 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...
1557
            $qb = $em
1558
                ->createQuery('
1559
                    SELECT s.sessionAdminId FROM ChamiloCoreBundle:Session s
1560
                    WHERE s.id = ?1
1561
                ')
1562
                ->setParameter(1, $id_checked);
1563
1564
            $res = $qb->getSingleScalarResult();
1565
1566
            if ($res != $userId && !api_is_platform_admin()) {
1567
                api_not_allowed(true);
1568
            }
1569
        }
1570
1571
        // Delete documents inside a session
1572
        $courses = SessionManager::getCoursesInSession($id_checked);
1573
        foreach ($courses as $courseId) {
1574
            $courseInfo = api_get_course_info_by_id($courseId);
1575
            DocumentManager::deleteDocumentsFromSession($courseInfo, $id_checked);
0 ignored issues
show
Bug introduced by
It seems like $id_checked defined by parameter $id_checked on line 1533 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...
1576
1577
            $works = Database::select(
1578
                '*',
1579
                $tbl_student_publication,
1580
                [
1581
                    'where' => ['session_id = ? AND c_id = ?' => [$id_checked, $courseId]]
1582
                ]
1583
            );
1584
1585
            $currentCourseRepositorySys = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/';
1586
1587
            foreach ($works as $index => $work) {
1588
                if ($work['filetype'] = 'folder') {
1589
                    Database::query("DELETE FROM $tbl_student_publication_assignment WHERE publication_id = $index");
1590
                }
1591
                my_delete($currentCourseRepositorySys.'/'.$work['url']);
1592
            }
1593
        }
1594
1595
        Database::query("DELETE FROM $tbl_student_publication WHERE session_id IN($id_checked)");
1596
        Database::query("DELETE FROM $tbl_session_rel_course WHERE session_id IN($id_checked)");
1597
        Database::query("DELETE FROM $tbl_session_rel_course_rel_user WHERE session_id IN($id_checked)");
1598
        Database::query("DELETE FROM $tbl_session_rel_user WHERE session_id IN($id_checked)");
1599
        Database::query("DELETE FROM $tbl_item_properties WHERE session_id IN ($id_checked)");
1600
        Database::query("DELETE FROM $tbl_url_session WHERE session_id IN($id_checked)");
1601
1602
        $sql = "UPDATE $ticket SET session_id = NULL WHERE session_id IN ($id_checked)";
1603
        Database::query($sql);
1604
1605
        $sql = "DELETE FROM $tbl_session WHERE id IN ($id_checked)";
1606
        Database::query($sql);
1607
1608
        $extraFieldValue = new ExtraFieldValue('session');
1609
        $extraFieldValue->deleteValuesByItem($id_checked);
0 ignored issues
show
Bug introduced by
It seems like $id_checked defined by parameter $id_checked on line 1533 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...
1610
1611
        /** @var \Chamilo\CoreBundle\Entity\Repository\SequenceRepository $repo */
1612
        $repo = Database::getManager()->getRepository('ChamiloCoreBundle:SequenceResource');
1613
        $repo->deleteResource(
1614
            $id_checked,
0 ignored issues
show
Bug introduced by
It seems like $id_checked defined by parameter $id_checked on line 1533 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...
1615
            \Chamilo\CoreBundle\Entity\SequenceResource::SESSION_TYPE
1616
        );
1617
1618
        // Add event to system log
1619
        Event::addEvent(
1620
            LOG_SESSION_DELETE,
1621
            LOG_SESSION_ID,
1622
            $id_checked,
1623
            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...
1624
            $userId
1625
        );
1626
    }
1627
1628
    /**
1629
     * @param int $id promotion id
1630
     *
1631
     * @return bool
1632
     */
1633 View Code Duplication
    public static function clear_session_ref_promotion($id)
1634
    {
1635
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1636
        $id = intval($id);
1637
        $sql = "UPDATE $tbl_session 
1638
                SET promotion_id = 0
1639
                WHERE promotion_id = $id";
1640
        if (Database::query($sql)) {
1641
            return true;
1642
        } else {
1643
            return false;
1644
        }
1645
    }
1646
1647
    /**
1648
     * Subscribes students to the given session and optionally (default) unsubscribes previous users
1649
     *
1650
     * @author Carlos Vargas from existing code
1651
     * @author Julio Montoya. Cleaning code.
1652
     * @param int $id_session
1653
     * @param array $user_list
1654
     * @param int $session_visibility
1655
     * @param bool $empty_users
1656
     * @return bool
1657
     */
1658
    public static function subscribe_users_to_session(
1659
        $id_session,
1660
        $user_list,
1661
        $session_visibility = SESSION_VISIBLE_READ_ONLY,
1662
        $empty_users = true
1663
    ) {
1664
        if ($id_session != strval(intval($id_session))) {
1665
            return false;
1666
        }
1667
1668
        foreach ($user_list as $intUser) {
1669
            if ($intUser != strval(intval($intUser))) {
1670
                return false;
1671
            }
1672
        }
1673
1674
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1675
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1676
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1677
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1678
1679
        $entityManager = Database::getManager();
1680
        $session = $entityManager->find('ChamiloCoreBundle:Session', $id_session);
1681
1682
        // from function parameter
1683
        if (empty($session_visibility)) {
1684
            $session_visibility = $session->getVisibility();
1685
            //default status loaded if empty
1686
            // by default readonly 1
1687
            if (empty($session_visibility)) {
1688
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
1689
            }
1690
        } else {
1691
            if (!in_array($session_visibility, array(SESSION_VISIBLE_READ_ONLY, SESSION_VISIBLE, SESSION_INVISIBLE))) {
1692
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
1693
            }
1694
        }
1695
1696
        $sql = "SELECT user_id FROM $tbl_session_rel_course_rel_user
1697
                WHERE session_id = $id_session AND status = 0";
1698
        $result = Database::query($sql);
1699
        $existingUsers = array();
1700
        while ($row = Database::fetch_array($result)) {
1701
            $existingUsers[] = $row['user_id'];
1702
        }
1703
1704
        $sql = "SELECT c_id FROM $tbl_session_rel_course
1705
                WHERE session_id = $id_session";
1706
        $result = Database::query($sql);
1707
        $course_list = array();
1708
        while ($row = Database::fetch_array($result)) {
1709
            $course_list[] = $row['c_id'];
1710
        }
1711
1712
        if ($session->getSendSubscriptionNotification() &&
1713
            is_array($user_list)
1714
        ) {
1715
            // Sending emails only
1716
            foreach ($user_list as $user_id) {
1717
                if (in_array($user_id, $existingUsers)) {
1718
                    continue;
1719
                }
1720
1721
                $tplSubject = new Template(null, false, false, false, false, false);
1722
                $layoutSubject = $tplSubject->get_template(
1723
                    'mail/subject_subscription_to_session_confirmation.tpl'
1724
                );
1725
                $subject = $tplSubject->fetch($layoutSubject);
1726
1727
                $user_info = api_get_user_info($user_id);
1728
1729
                $tplContent = new Template(null, false, false, false, false, false);
1730
                // Variables for default template
1731
                $tplContent->assign(
1732
                    'complete_name',
1733
                    stripslashes($user_info['complete_name'])
1734
                );
1735
                $tplContent->assign('session_name', $session->getName());
1736
                $tplContent->assign(
1737
                    'session_coach',
1738
                    $session->getGeneralCoach()->getCompleteName()
1739
                );
1740
                $layoutContent = $tplContent->get_template(
1741
                    'mail/content_subscription_to_session_confirmation.tpl'
1742
                );
1743
                $content = $tplContent->fetch($layoutContent);
1744
1745
                api_mail_html(
1746
                    $user_info['complete_name'],
1747
                    $user_info['mail'],
1748
                    $subject,
1749
                    $content,
1750
                    api_get_person_name(
1751
                        api_get_setting('administratorName'),
1752
                        api_get_setting('administratorSurname')
1753
                    ),
1754
                    api_get_setting('emailAdministrator')
1755
                );
1756
            }
1757
        }
1758
1759
        foreach ($course_list as $courseId) {
1760
            // for each course in the session
1761
            $nbr_users = 0;
1762
            $courseId = intval($courseId);
1763
1764
            $sql = "SELECT DISTINCT user_id
1765
                    FROM $tbl_session_rel_course_rel_user
1766
                    WHERE
1767
                        session_id = $id_session AND
1768
                        c_id = $courseId AND
1769
                        status = 0
1770
                    ";
1771
            $result = Database::query($sql);
1772
            $existingUsers = array();
1773
            while ($row = Database::fetch_array($result)) {
1774
                $existingUsers[] = $row['user_id'];
1775
            }
1776
1777
            // Delete existing users
1778 View Code Duplication
            if ($empty_users) {
1779
                foreach ($existingUsers as $existing_user) {
1780
                    if (!in_array($existing_user, $user_list)) {
1781
                        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
1782
                                WHERE
1783
                                    session_id = $id_session AND
1784
                                    c_id = $courseId AND
1785
                                    user_id = $existing_user AND
1786
                                    status = 0 ";
1787
                        $result = Database::query($sql);
1788
1789
                        Event::addEvent(
1790
                            LOG_SESSION_DELETE_USER_COURSE,
1791
                            LOG_USER_ID,
1792
                            $existing_user,
1793
                            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...
1794
                            api_get_user_id(),
1795
                            $courseId,
1796
                            $id_session
1797
                        );
1798
1799
                        if (Database::affected_rows($result)) {
1800
                            $nbr_users--;
1801
                        }
1802
                    }
1803
                }
1804
            }
1805
1806
            // Replace with this new function
1807
            // insert new users into session_rel_course_rel_user and ignore if they already exist
1808
1809
            foreach ($user_list as $enreg_user) {
1810 View Code Duplication
                if (!in_array($enreg_user, $existingUsers)) {
1811
                    $enreg_user = Database::escape_string($enreg_user);
1812
                    $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id, visibility, status)
1813
                            VALUES($id_session, $courseId, $enreg_user, $session_visibility, 0)";
1814
                    $result = Database::query($sql);
1815
1816
                    Event::addEvent(
1817
                        LOG_SESSION_ADD_USER_COURSE,
1818
                        LOG_USER_ID,
1819
                        $enreg_user,
1820
                        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...
1821
                        api_get_user_id(),
1822
                        $courseId,
1823
                        $id_session
1824
                    );
1825
1826
                    if (Database::affected_rows($result)) {
1827
1828
                        $nbr_users++;
1829
                    }
1830
                }
1831
            }
1832
1833
            // Count users in this session-course relation
1834
            $sql = "SELECT COUNT(user_id) as nbUsers
1835
                    FROM $tbl_session_rel_course_rel_user
1836
                    WHERE session_id = $id_session AND c_id = $courseId AND status<>2";
1837
            $rs = Database::query($sql);
1838
            list($nbr_users) = Database::fetch_array($rs);
0 ignored issues
show
Bug introduced by
It seems like $rs can be null; however, fetch_array() does not accept null, maybe add an additional type check?

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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

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

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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

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

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

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

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

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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