Test Setup Failed
Push — master ( f71949...6c6bd7 )
by Julito
55:21
created

SessionManager::getTeacherTracking()   C

Complexity

Conditions 14
Paths 100

Size

Total Lines 81
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 52
nc 100
nop 5
dl 0
loc 81
rs 5.0042
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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

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

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

    return array();
}

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

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

Loading history...
5091
                                                $data['c_id']
5092
                                            );
5093
                                        }
5094
                                    }
5095
5096 View Code Duplication
                                    if (isset($groupBackup['tutor'][$teacherToAdd]) &&
5097
                                        isset($groupBackup['tutor'][$teacherToAdd][$course_code]) &&
5098
                                        !empty($groupBackup['tutor'][$teacherToAdd][$course_code])
5099
                                    ) {
5100
                                        foreach ($groupBackup['tutor'][$teacherToAdd][$course_code] as $data) {
5101
                                            $groupInfo = GroupManager::get_group_properties($data['group_id']);
5102
                                            GroupManager::subscribe_tutors(
5103
                                                $teacherToAdd,
5104
                                                $groupInfo,
5105
                                                $data['c_id']
5106
                                            );
5107
                                        }
5108
                                    }
5109
                                }
5110
                            }
5111
5112
                            // See BT#6449#note-195
5113
                            // All coaches are added.
5114
                            if ($removeAllTeachersFromCourse) {
5115
                                if ($debug) {
5116
                                    $logger->addInfo("removeAllTeachersFromCourse true");
5117
                                }
5118
                                $teacherToAdd = null;
5119 View Code Duplication
                                foreach ($course_coaches as $course_coach) {
5120
                                    $coach_id = UserManager::get_user_id_from_username(
5121
                                        $course_coach
5122
                                    );
5123
                                    if ($coach_id !== false) {
5124
                                        $teacherToAdd[] = $coach_id;
5125
                                    }
5126
                                }
5127
5128
                                if (!empty($teacherToAdd)) {
5129
                                    // Deleting all course teachers and adding the only coach as teacher.
5130
                                    $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
5131
5132 View Code Duplication
                                    if (!empty($teacherList)) {
5133
                                        foreach ($teacherList as $teacher) {
5134
                                            if (!in_array($teacher['user_id'], $teacherToAdd)) {
5135
                                                $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
5136
                                                        WHERE
5137
                                                            user_id = ".$teacher['user_id']." AND
5138
                                                            c_id = '".$courseId."'
5139
                                                        ";
5140
5141
                                                $result = Database::query($sql);
5142
                                                $rows = Database::num_rows($result);
5143
                                                if ($rows > 0) {
5144
                                                    $userCourseData = Database::fetch_array($result, 'ASSOC');
5145
                                                    if (!empty($userCourseData)) {
5146
                                                        $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
5147
                                                    }
5148
                                                }
5149
5150
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
5151
                                                        WHERE
5152
                                                            user_id = ".$teacher['user_id']." AND
5153
                                                            c_id = '".$courseInfo['real_id']."'
5154
                                                        ";
5155
5156
                                                $result = Database::query($sql);
5157
                                                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5158
                                                    $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5159
                                                }
5160
5161
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
5162
                                                        WHERE
5163
                                                            user_id = ".$teacher['user_id']." AND
5164
                                                            c_id = '".$courseInfo['real_id']."'
5165
                                                        ";
5166
5167
                                                $result = Database::query($sql);
5168
                                                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5169
                                                    $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5170
                                                }
5171
5172
                                                CourseManager::unsubscribe_user(
5173
                                                    $teacher['user_id'],
5174
                                                    $course_code
5175
                                                );
5176
5177
                                                if ($debug) {
5178
                                                    $logger->addInfo("Delete user #".$teacher['user_id']." from base course: $course_code");
5179
                                                }
5180
                                            }
5181
                                        }
5182
                                    }
5183
5184
                                    foreach ($teacherToAdd as $teacherId) {
5185
                                        $userCourseCategory = '';
5186 View Code Duplication
                                        if (isset($teacherBackupList[$teacherId]) &&
5187
                                            isset($teacherBackupList[$teacherId][$course_code])
5188
                                        ) {
5189
                                            $courseUserData = $teacherBackupList[$teacherId][$course_code];
5190
                                            $userCourseCategory = $courseUserData['user_course_cat'];
5191
                                        }
5192
5193
                                        CourseManager::subscribe_user(
5194
                                            $teacherId,
5195
                                            $course_code,
5196
                                            COURSEMANAGER,
5197
                                            0,
5198
                                            $userCourseCategory
5199
                                        );
5200
5201
                                        if ($debug) {
5202
                                            $logger->addInfo("Add user as teacher #".$teacherId." in base course: $course_code with userCourseCategory: $userCourseCategory");
5203
                                        }
5204
5205 View Code Duplication
                                        if (isset($groupBackup['user'][$teacherId]) &&
5206
                                            isset($groupBackup['user'][$teacherId][$course_code]) &&
5207
                                            !empty($groupBackup['user'][$teacherId][$course_code])
5208
                                        ) {
5209
                                            foreach ($groupBackup['user'][$teacherId][$course_code] as $data) {
5210
                                                $groupInfo = GroupManager::get_group_properties($data['group_id']);
5211
                                                GroupManager::subscribe_users(
5212
                                                    $teacherId,
5213
                                                    $groupInfo,
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by \GroupManager::get_group...ties($data['group_id']) on line 5210 can also be of type null; however, GroupManager::subscribe_users() does only seem to accept array, maybe add an additional type check?

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

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

    return array();
}

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

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

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

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

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

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

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

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

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

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

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

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

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