Completed
Push — 1.11.x ( d84d27...922b6f )
by José
30:17
created

SessionManager::getAllCoursesFromAllSessions()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

// Bar.php
namespace OtherDir;

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

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

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

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

// Bar.php
namespace OtherDir;

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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

There are different options of fixing this problem.

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

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

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

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

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

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

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

could be turned into

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

This is much more concise to read.

Loading history...
559
                    } else {
560
                        $key = str_replace('_second', '', $key);
561
                    }
562
563
                    if (isset($options_by_double[$key])) {
564
                        if (isset($options[0])) {
565
                            if (isset($options_by_double[$key][$options[0]])) {
566
                                if (strpos($original_key, '_second') === false) {
567
                                    $value = $options_by_double[$key][$options[0]]['option_display_text'];
568
                                } else {
569
                                    $value = $options_by_double[$key][$options[1]]['option_display_text'];
570
                                }
571
                            }
572
                        }
573
                    }
574
                }
575
                $formatted_sessions[$session_id] = $session;
576
                $categoryName = isset($orderedCategories[$session['session_category_id']]) ? $orderedCategories[$session['session_category_id']] : '';
577
                $formatted_sessions[$session_id]['category_name'] = $categoryName;
578
            }
579
        }
580
        return $formatted_sessions;
581
    }
582
583
    /**
584
     *  Get total of records for progress of learning paths in the given session
585
     *  @param int session id
586
     *  @return int
587
     */
588
    public static function get_count_session_lp_progress($sessionId = 0)
589
    {
590
        $tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
591
        $tbl_lp_view = Database::get_course_table(TABLE_LP_VIEW);
592
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
593
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
594
595
        $sessionId = intval($sessionId);
596
597
        $sql = "SELECT  count(*) as total_rows
598
                FROM $tbl_lp_view v
599
                INNER JOIN $tbl_lp l ON l.id = v.lp_id
600
                INNER JOIN $tbl_user u ON u.user_id = v.user_id
601
                INNER JOIN $tbl_course c
602
                WHERE v.session_id = " . $sessionId;
603
        $result_rows = Database::query($sql);
604
        $row = Database::fetch_array($result_rows);
605
        $num = $row['total_rows'];
606
607
        return $num;
608
    }
609
610
    /**
611
     * Gets the progress of learning paths in the given session
612
     * @param int   $sessionId
613
     * @param int $courseId
614
     * @param string $date_from
615
     * @param string $date_to
616
     * @param array options order and limit keys
617
     * @return array table with user name, lp name, progress
618
     */
619
    public static function get_session_lp_progress($sessionId = 0, $courseId = 0, $date_from, $date_to, $options)
620
    {
621
        //escaping vars
622
        $sessionId = $sessionId == 'T' ? 'T' : intval($sessionId);
623
        $courseId = intval($courseId);
624
        $date_from = Database :: escape_string($date_from);
625
        $date_to = Database :: escape_string($date_to);
626
627
        //tables
628
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
629
        $user = Database::get_main_table(TABLE_MAIN_USER);
630
        $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
631
632
        $course = api_get_course_info_by_id($courseId);
633
634
        //getting all the students of the course
635
        //we are not using this because it only returns user ids
636
        /* if (empty($sessionId)
637
          {
638
          // Registered students in a course outside session.
639
          $users = CourseManager :: get_student_list_from_course_code($course_code);
640
          } else {
641
          // Registered students in session.
642
          $users = CourseManager :: get_student_list_from_course_code($course_code, true, $sessionId);
643
          } */
644
645
        $sessionCond = 'and session_id = %s';
646
        if ($sessionId == 'T') {
647
            $sessionCond = "";
648
        }
649
650
        $where = " WHERE c_id = '%s' AND s.status <> 2 $sessionCond";
651
652
        $limit = null;
653
        if (!empty($options['limit'])) {
654
            $limit = " LIMIT " . $options['limit'];
655
        }
656
657
        if (!empty($options['where'])) {
658
            $where .= ' '.$options['where'];
659
        }
660
661
        $order = null;
662
        if (!empty($options['order'])) {
663
            $order = " ORDER BY " . $options['order'];
664
        }
665
666
        $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
667
                FROM $session_course_user s
668
                INNER JOIN $user u ON u.user_id = s.user_id
669
                $where
670
                $order
671
                $limit";
672
673
        $sql_query = sprintf($sql, Database::escape_string($course['real_id']), $sessionId);
674
675
        $rs = Database::query($sql_query);
676
        while ($user = Database::fetch_array($rs)) {
677
            $users[$user['user_id']] = $user;
678
        }
679
680
        //Get lessons
681
        $lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
682
683
        $table = array();
684
        foreach ($users as $user) {
685
            $data = array(
686
                'lastname' => $user[1],
687
                'firstname' => $user[2],
688
                'username' => $user[3],
689
            );
690
691
            $sessionCond = 'AND v.session_id = %d';
692
            if ($sessionId == 'T') {
693
                $sessionCond = "";
694
            }
695
696
            //Get lessons progress by user
697
            $sql = "SELECT v.lp_id as id, v.progress
698
                    FROM  $tbl_course_lp_view v
699
                    WHERE v.c_id = %d
700
                    AND v.user_id = %d
701
            $sessionCond";
702
703
            $sql_query = sprintf($sql,
704
                intval($courseId),
705
                intval($user['user_id']),
706
                $sessionId
707
            );
708
709
            $result = Database::query($sql_query);
710
711
            $user_lessons = array();
712
            while ($row = Database::fetch_array($result)) {
713
                $user_lessons[$row['id']] = $row;
714
            }
715
716
            //Match course lessons with user progress
717
            $progress = 0;
718
            $count = 0;
719
            foreach ($lessons as $lesson) {
720
                $data[$lesson['id']] = (!empty($user_lessons[$lesson['id']]['progress'])) ? $user_lessons[$lesson['id']]['progress'] : 0;
721
                $progress += $data[$lesson['id']];
722
                $data[$lesson['id']] = $data[$lesson['id']] . '%';
723
                $count++;
724
            }
725
            if ($count == 0) {
726
                $data['total'] = 0;
727
            } else {
728
                $data['total'] = round($progress / $count, 2) . '%';
729
            }
730
            $table[] = $data;
731
        }
732
733
        return $table;
734
    }
735
736
    /**
737
     * Gets the survey answers
738
     * @param int   $sessionId
739
     * @param int   $courseId
740
     * @param int   $surveyId
741
     * @param array options order and limit keys
742
     * @todo fix the query
743
     * @return array table with user name, lp name, progress
744
     */
745
    public static function get_survey_overview($sessionId = 0, $courseId = 0, $surveyId = 0, $date_from, $date_to, $options)
746
    {
747
        //escaping vars
748
        $sessionId = intval($sessionId);
749
        $courseId = intval($courseId);
750
        $surveyId = intval($surveyId);
751
        $date_from = Database::escape_string($date_from);
752
        $date_to = Database::escape_string($date_to);
753
754
        //tables
755
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
756
        $user = Database::get_main_table(TABLE_MAIN_USER);
757
        $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
758
        $c_survey = Database::get_course_table(TABLE_SURVEY);
759
        $c_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
760
        $c_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
761
        $c_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
762
763
        $course = api_get_course_info_by_id($courseId);
764
765
        $where = " WHERE c_id = '%s' AND s.status <> 2 AND session_id = %s";
766
767
        $limit = null;
768
        if (!empty($options['limit'])) {
769
            $limit = " LIMIT " . $options['limit'];
770
        }
771
772
        if (!empty($options['where'])) {
773
            $where .= ' '.$options['where'];
774
        }
775
776
        $order = null;
777
        if (!empty($options['order'])) {
778
            $order = " ORDER BY " . $options['order'];
779
        }
780
781
        $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
782
                FROM $session_course_user s
783
                INNER JOIN $user u ON u.user_id = s.user_id
784
                $where $order $limit";
785
786
        $sql_query = sprintf($sql, intval($course['real_id']), $sessionId);
787
        $rs = Database::query($sql_query);
788
        while ($user = Database::fetch_array($rs)) {
789
            $users[$user['user_id']] = $user;
790
        }
791
792
        //Get survey questions
793
        $questions = SurveyManager::get_questions($surveyId, $courseId);
794
795
        //Survey is anonymous?
796
        $result = Database::query(sprintf("SELECT anonymous FROM $c_survey WHERE survey_id = %d", $surveyId));
797
        $row = Database::fetch_array($result);
798
        $anonymous = ($row['anonymous'] == 1) ? true : false;
799
800
        $table = array();
801
        foreach ($users as $user) {
802
            $data = array(
803
                'lastname' => ($anonymous ? '***' : $user[1]),
804
                'firstname' => ($anonymous ? '***' : $user[2]),
805
                'username' => ($anonymous ? '***' : $user[3]),
806
            );
807
808
            //Get questions by user
809
            $sql = "SELECT sa.question_id, sa.option_id, sqo.option_text, sq.type
810
                    FROM $c_survey_answer sa
811
                    INNER JOIN $c_survey_question sq
812
                    ON sq.question_id = sa.question_id
813
                    LEFT JOIN $c_survey_question_option sqo
814
                    ON
815
                      sqo.c_id = sa.c_id AND
816
                      sqo.question_id = sq.question_id AND
817
                      sqo.question_option_id = sa.option_id AND
818
                      sqo.survey_id = sq.survey_id
819
                    WHERE
820
                      sa.survey_id = %d AND
821
                      sa.c_id = %d AND
822
                      sa.user = %d
823
            "; //. $where_survey;
824
            $sql_query = sprintf($sql, $surveyId, $courseId, $user['user_id']);
825
826
            $result = Database::query($sql_query);
827
828
            $user_questions = array();
829
            while ($row = Database::fetch_array($result)) {
830
                $user_questions[$row['question_id']] = $row;
831
            }
832
833
            //Match course lessons with user progress
834
            foreach ($questions as $question_id => $question) {
835
                $option_text = 'option_text';
836
                if ($user_questions[$question_id]['type'] == 'open') {
837
                    $option_text = 'option_id';
838
                }
839
                $data[$question_id] = $user_questions[$question_id][$option_text];
840
            }
841
842
            $table[] = $data;
843
        }
844
        return $table;
845
    }
846
847
    /**
848
     * Gets the progress of the given session
849
     * @param int   $sessionId
850
     * @param int   $courseId
851
     * @param array options order and limit keys
852
     *
853
     * @return array table with user name, lp name, progress
854
     */
855
    public static function get_session_progress($sessionId, $courseId, $date_from, $date_to, $options)
856
    {
857
        $sessionId = intval($sessionId);
858
859
        $getAllSessions = false;
860
        if (empty($sessionId)) {
861
            $sessionId = 0;
862
            $getAllSessions = true;
863
        }
864
865
        //tables
866
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
867
        $user = Database::get_main_table(TABLE_MAIN_USER);
868
        $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
869
        $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
870
        $tbl_course_lp = Database::get_course_table(TABLE_LP_MAIN);
871
        $wiki = Database::get_course_table(TABLE_WIKI);
872
        $table_stats_default = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
873
        $table_stats_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
874
875
        $course = api_get_course_info_by_id($courseId);
876
        $where = " WHERE c_id = '%s' AND s.status <> 2 ";
877
878
        $limit = null;
879
        if (!empty($options['limit'])) {
880
            $limit = " LIMIT " . $options['limit'];
881
        }
882
883
        if (!empty($options['where'])) {
884
            $where .= ' '.$options['where'];
885
        }
886
887
        $order = null;
888
        if (!empty($options['order'])) {
889
            $order = " ORDER BY " . $options['order'];
890
        }
891
892
        //TODO, fix create report without session
893
        $queryVariables = array($course['real_id']);
894
        if (!empty($sessionId)) {
895
            $where .= ' AND session_id = %s';
896
            $queryVariables[] = $sessionId;
897
            $sql = "SELECT
898
                        u.user_id, u.lastname, u.firstname, u.username,
899
                        u.email, s.c_id, s.session_id
900
                    FROM $session_course_user s
901
                    INNER JOIN $user u
902
                    ON u.user_id = s.user_id
903
                    $where $order $limit";
904
        } else {
905
            $sql = "SELECT
906
                        u.user_id, u.lastname, u.firstname, u.username,
907
                        u.email, s.c_id, s.session_id
908
                    FROM $session_course_user s
909
                    INNER JOIN $user u ON u.user_id = s.user_id
910
                    $where $order $limit";
911
        }
912
913
        $sql_query = vsprintf($sql, $queryVariables);
914
        $rs = Database::query($sql_query);
915
        while ($user = Database::fetch_array($rs)) {
916
            $users[$user['user_id']] = $user;
917
        }
918
919
        /**
920
         *  Lessons
921
         */
922
        $sql = "SELECT * FROM $tbl_course_lp WHERE c_id = %s ";  //AND session_id = %s
923
        $sql_query = sprintf($sql, $course['real_id']);
924
        $result = Database::query($sql_query);
925
        $arrLesson = array(array());
926
        while ($row = Database::fetch_array($result)) {
927
            if (empty($arrLesson[$row['session_id']]['lessons_total'])) {
928
                $arrLesson[$row['session_id']]['lessons_total'] = 1;
929
            } else {
930
                $arrLesson[$row['session_id']]['lessons_total'] ++;
931
            }
932
        }
933
934
        /**
935
         *  Exercises
936
         */
937
        $exercises = ExerciseLib::get_all_exercises($course, $sessionId, false, '', $getAllSessions);
938
        $exercises_total = count($exercises);
939
940
        /**
941
         *  Assignments
942
         */
943
        //total
944
        $params = [$course['real_id']];
945
        if ($getAllSessions) {
946
            $sql = "SELECT count(w.id) as count
947
                    FROM $workTable w
948
                    LEFT JOIN $workTableAssignment a
949
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
950
                    WHERE 
951
                        w.c_id = %s AND 
952
                        parent_id = 0 AND 
953
                        active IN (1, 0)";
954
        } else {
955
            $sql = "SELECT count(w.id) as count
956
                    FROM $workTable w
957
                    LEFT JOIN $workTableAssignment a
958
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
959
                    WHERE 
960
                        w.c_id = %s AND 
961
                        parent_id = 0 AND 
962
                        active IN (1, 0)";
963
964
            if (empty($sessionId)) {
965
                $sql .= ' AND w.session_id = NULL ';
966
            } else {
967
                $sql .= ' AND w.session_id = %s ';
968
                $params[] = $sessionId;
969
            }
970
        }
971
972
        $sql_query = vsprintf($sql, $params);
973
        $result = Database::query($sql_query);
974
        $row = Database::fetch_array($result);
975
        $assignments_total = $row['count'];
976
977
        /**
978
         * Wiki
979
         */
980
        if ($getAllSessions) {
981
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
982
                    WHERE c_id = %s";
983
        } else {
984
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
985
                    WHERE c_id = %s and session_id = %s";
986
        }
987
        $sql_query = sprintf($sql, $course['real_id'], $sessionId);
988
        $result = Database::query($sql_query);
989
        $row = Database::fetch_array($result);
990
        $wiki_total = $row['count'];
991
992
        /**
993
         * Surveys
994
         */
995
        $survey_user_list = array();
996
        $survey_list = SurveyManager::get_surveys($course['code'], $sessionId);
997
998
        $surveys_total = count($survey_list);
999 View Code Duplication
        foreach ($survey_list as $survey) {
0 ignored issues
show
Bug introduced by
The expression $survey_list of type false|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

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

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

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

Loading history...
1000
            $user_list = SurveyManager::get_people_who_filled_survey(
1001
                $survey['survey_id'],
1002
                false,
1003
                $course['real_id']
1004
            );
1005
            foreach ($user_list as $user_id) {
1006
                isset($survey_user_list[$user_id]) ? $survey_user_list[$user_id] ++ : $survey_user_list[$user_id] = 1;
1007
            }
1008
        }
1009
1010
        /**
1011
         * Forums
1012
         */
1013
        $forums_total = CourseManager::getCountForum(
1014
            $course['real_id'],
1015
            $sessionId,
1016
            $getAllSessions
1017
        );
1018
1019
        //process table info
1020
        foreach ($users as $user) {
1021
            //Course description
1022
            $sql = "SELECT count(*) as count
1023
                    FROM $table_stats_access
1024
                    WHERE access_tool = 'course_description'
1025
                    AND c_id = '%s'
1026
                    AND access_session_id = %s
1027
                    AND access_user_id = %s ";
1028
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1029
1030
            $result = Database::query($sql_query);
1031
            $row = Database::fetch_array($result);
1032
            $course_description_progress = ($row['count'] > 0) ? 100 : 0;
1033
1034
            if (!empty($arrLesson[$user['id_session']]['lessons_total'])) {
1035
                $lessons_total = $arrLesson[$user['id_session']]['lessons_total'];
1036
            } else {
1037
                $lessons_total = !empty($arrLesson[0]['lessons_total']) ? $arrLesson[0]['lessons_total'] : 0;
1038
            }
1039
1040
            //Lessons
1041
            //TODO: Lessons done and left is calculated by progress per item in lesson, maybe we should calculate it only per completed lesson?
1042
            $lessons_progress = Tracking::get_avg_student_progress(
1043
                $user['user_id'],
1044
                $course['code'],
1045
                array(),
1046
                $user['id_session']
1047
            );
1048
            $lessons_done = ($lessons_progress * $lessons_total) / 100;
1049
            $lessons_left = $lessons_total - $lessons_done;
1050
1051
            //Exercises
1052
            $exercises_progress = str_replace('%', '', Tracking::get_exercise_student_progress($exercises, $user['user_id'], $course['real_id'], $user['id_session']));
1053
            $exercises_done = round(($exercises_progress * $exercises_total) / 100);
1054
            $exercises_left = $exercises_total - $exercises_done;
1055
1056
            //Assignments
1057
            $assignments_done = Tracking::count_student_assignments($user['user_id'], $course['code'], $user['id_session']);
1058
            $assignments_left = $assignments_total - $assignments_done;
1059
            if (!empty($assignments_total)) {
1060
                $assignments_progress = round((( $assignments_done * 100 ) / $assignments_total), 2);
1061
            } else {
1062
                $assignments_progress = 0;
1063
            }
1064
1065
            //Wiki
1066
            //total revisions per user
1067
            $sql = "SELECT count(*) as count
1068
                    FROM $wiki
1069
                    WHERE c_id = %s and session_id = %s and user_id = %s";
1070
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1071
            $result = Database::query($sql_query);
1072
            $row = Database::fetch_array($result);
1073
            $wiki_revisions = $row['count'];
1074
            //count visited wiki pages
1075
            $sql = "SELECT count(distinct default_value) as count
1076
                    FROM $table_stats_default
1077
                    WHERE
1078
                        default_user_id = %s AND
1079
                        default_event_type = 'wiki_page_view' AND
1080
                        default_value_type = 'wiki_page_id' AND
1081
                        c_id = %s
1082
                    ";
1083
            $sql_query = sprintf($sql, $user['user_id'], $course['real_id']);
1084
            $result = Database::query($sql_query);
1085
            $row = Database::fetch_array($result);
1086
1087
            $wiki_read = $row['count'];
1088
            $wiki_unread = $wiki_total - $wiki_read;
1089
            if (!empty($wiki_total)) {
1090
                $wiki_progress = round((( $wiki_read * 100 ) / $wiki_total), 2);
1091
            } else {
1092
                $wiki_progress = 0;
1093
            }
1094
1095
            //Surveys
1096
            $surveys_done = (isset($survey_user_list[$user['user_id']]) ? $survey_user_list[$user['user_id']] : 0);
1097
            $surveys_left = $surveys_total - $surveys_done;
1098
            if (!empty($surveys_total)) {
1099
                $surveys_progress = round((( $surveys_done * 100 ) / $surveys_total), 2);
1100
            } else {
1101
                $surveys_progress = 0;
1102
            }
1103
1104
            //Forums
1105
            $forums_done = CourseManager::getCountForumPerUser(
1106
                $user['user_id'],
1107
                $course['real_id'],
1108
                $user['id_session']
1109
            );
1110
            $forums_left = $forums_total - $forums_done;
1111
            if (!empty($forums_total)) {
1112
                $forums_progress = round((( $forums_done * 100 ) / $forums_total), 2);
1113
            } else {
1114
                $forums_progress = 0;
1115
            }
1116
1117
            //Overall Total
1118
            $overall_total = ($course_description_progress + $exercises_progress + $forums_progress + $assignments_progress + $wiki_progress + $surveys_progress) / 6;
1119
1120
            $link = '<a href="' . api_get_path(WEB_CODE_PATH) . 'mySpace/myStudents.php?student=' . $user[0] . '&details=true&course=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1121
            $linkForum = '<a href="' . api_get_path(WEB_CODE_PATH) . 'forum/index.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1122
            $linkWork = '<a href="' . api_get_path(WEB_CODE_PATH) . 'work/work.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1123
            $linkWiki = '<a href="' . api_get_path(WEB_CODE_PATH) . 'wiki/index.php?cidReq=' . $course['code'] . '&session_id=' . $user['id_session'] . '&action=statistics"> %s </a>';
1124
            $linkSurvey = '<a href="' . api_get_path(WEB_CODE_PATH) . 'survey/survey_list.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1125
1126
            $table[] = array(
1127
                'lastname' => $user[1],
1128
                'firstname' => $user[2],
1129
                'username' => $user[3],
1130
                #'profile'   => '',
1131
                'total' => round($overall_total, 2) . '%',
1132
                'courses' => sprintf($link, $course_description_progress . '%'),
1133
                'lessons' => sprintf($link, $lessons_progress . '%'),
1134
                'exercises' => sprintf($link, $exercises_progress . '%'),
1135
                'forums' => sprintf($link, $forums_progress . '%'),
1136
                'homeworks' => sprintf($link, $assignments_progress . '%'),
1137
                'wikis' => sprintf($link, $wiki_progress . '%'),
1138
                'surveys' => sprintf($link, $surveys_progress . '%'),
1139
                //course description
1140
                'course_description_progress' => $course_description_progress . '%',
1141
                //lessons
1142
                'lessons_total' => sprintf($link, $lessons_total),
1143
                'lessons_done' => sprintf($link, $lessons_done),
1144
                'lessons_left' => sprintf($link, $lessons_left),
1145
                'lessons_progress' => sprintf($link, $lessons_progress . '%'),
1146
                //exercises
1147
                'exercises_total' => sprintf($link, $exercises_total),
1148
                'exercises_done' => sprintf($link, $exercises_done),
1149
                'exercises_left' => sprintf($link, $exercises_left),
1150
                'exercises_progress' => sprintf($link, $exercises_progress . '%'),
1151
                //forums
1152
                'forums_total' => sprintf($linkForum, $forums_total),
1153
                'forums_done' => sprintf($linkForum, $forums_done),
1154
                'forums_left' => sprintf($linkForum, $forums_left),
1155
                'forums_progress' => sprintf($linkForum, $forums_progress . '%'),
1156
                //assignments
1157
                'assignments_total' => sprintf($linkWork, $assignments_total),
1158
                'assignments_done' => sprintf($linkWork, $assignments_done),
1159
                'assignments_left' => sprintf($linkWork, $assignments_left),
1160
                'assignments_progress' => sprintf($linkWork, $assignments_progress . '%'),
1161
                //wiki
1162
                'wiki_total' => sprintf($linkWiki, $wiki_total),
1163
                'wiki_revisions' => sprintf($linkWiki, $wiki_revisions),
1164
                'wiki_read' => sprintf($linkWiki, $wiki_read),
1165
                'wiki_unread' => sprintf($linkWiki, $wiki_unread),
1166
                'wiki_progress' => sprintf($linkWiki, $wiki_progress . '%'),
1167
                //survey
1168
                'surveys_total' => sprintf($linkSurvey, $surveys_total),
1169
                'surveys_done' => sprintf($linkSurvey, $surveys_done),
1170
                'surveys_left' => sprintf($linkSurvey, $surveys_left),
1171
                'surveys_progress' => sprintf($linkSurvey, $surveys_progress . '%'),
1172
            );
1173
        }
1174
1175
        return $table;
1176
    }
1177
1178
    /**
1179
     * @return int
1180
     */
1181 View Code Duplication
    public static function get_number_of_tracking_access_overview()
1182
    {
1183
        $table = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1184
        $sql = "SELECT COUNT(course_access_id) count FROM $table";
1185
        $result = Database::query($sql);
1186
        $row = Database::fetch_assoc($result);
1187
1188
        return $row['count'];
1189
    }
1190
1191
    /**
1192
     * Get the ip, total of clicks, login date and time logged in for all user, in one session
1193
     * @todo track_e_course_access table should have ip so we dont have to look for it in track_e_login
1194
     *
1195
     * @author César Perales <[email protected]>, Beeznest Team
1196
     * @version 1.9.6
1197
     */
1198
    public static function get_user_data_access_tracking_overview(
1199
        $sessionId,
1200
        $courseId,
1201
        $studentId = 0,
1202
        $profile = '',
1203
        $date_from = '',
1204
        $date_to = '',
1205
        $options
1206
    ) {
1207
        //escaping variables
1208
        $sessionId = intval($sessionId);
1209
        $courseId = intval($courseId);
1210
        $studentId = intval($studentId);
1211
        $profile = intval($profile);
1212
        $date_from = Database::escape_string($date_from);
1213
        $date_to = Database::escape_string($date_to);
1214
1215
        // database table definition
1216
        $user = Database :: get_main_table(TABLE_MAIN_USER);
1217
        $course = Database :: get_main_table(TABLE_MAIN_COURSE);
1218
        $track_e_login = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
1219
        $track_e_course_access = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1220
        $sessionTable = Database :: get_main_table(TABLE_MAIN_SESSION);
1221
1222
        global $export_csv;
1223
        if ($export_csv) {
1224
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
1225
        } else {
1226
            $is_western_name_order = api_is_western_name_order();
1227
        }
1228
1229
        $where = null;
1230
        if (isset($sessionId) && !empty($sessionId)) {
1231
            $where = sprintf(" WHERE a.session_id = %d", $sessionId);
1232
        }
1233
        if (isset($courseId) && !empty($courseId)) {
1234
            $where .= sprintf(" AND c.id = %d", $courseId);
1235
        }
1236
        if (isset($studentId) && !empty($studentId)) {
1237
            $where .= sprintf(" AND u.user_id = %d", $studentId);
1238
        }
1239
        if (isset($profile) && !empty($profile)) {
1240
            $where .= sprintf(" AND u.status = %d", $profile);
1241
        }
1242
        if (!empty($date_to) && !empty($date_from)) {
1243
            $where .= sprintf(
1244
                " AND a.login_course_date >= '%s 00:00:00'
1245
                 AND a.login_course_date <= '%s 23:59:59'",
1246
                $date_from,
1247
                $date_to
1248
            );
1249
        }
1250
1251
        $limit = null;
1252
        if (!empty($options['limit'])) {
1253
            $limit = " LIMIT " . $options['limit'];
1254
        }
1255
1256
        if (!empty($options['where'])) {
1257
            $where .= ' '.$options['where'];
1258
        }
1259
1260
        $order = null;
1261
        if (!empty($options['order'])) {
1262
            $order = " ORDER BY " . $options['order'];
1263
        }
1264
1265
        //TODO add course name
1266
        $sql = "SELECT
1267
                a.login_course_date ,
1268
                u.username ,
1269
                " . ($is_western_name_order ? "
1270
                    u.firstname,
1271
                    u.lastname,
1272
                    " : "
1273
                    u.lastname,
1274
                    u.firstname,
1275
                ") . "
1276
                a.logout_course_date,
1277
                a.counter,
1278
                c.title,
1279
                c.code,
1280
                u.user_id,
1281
                a.session_id
1282
            FROM $track_e_course_access a
1283
            INNER JOIN $user u ON a.user_id = u.user_id
1284
            INNER JOIN $course c ON a.c_id = c.id
1285
            $where $order $limit";
1286
        $result = Database::query(sprintf($sql, $sessionId, $courseId));
1287
1288
        $data = array();
1289
        while ($user = Database::fetch_assoc($result)) {
1290
            $data[] = $user;
1291
        }
1292
1293
        //foreach
1294
        foreach ($data as $key => $info) {
1295
            $sql = "SELECT
1296
                    name
1297
                    FROM $sessionTable
1298
                    WHERE
1299
                    id = {$info['session_id']}";
1300
            $result = Database::query($sql);
1301
            $session = Database::fetch_assoc($result);
1302
1303
            // building array to display
1304
            $return[] = array(
1305
                'user_id' => $info['user_id'],
1306
                'logindate' => $info['login_course_date'],
1307
                'username' => $info['username'],
1308
                'firstname' => $info['firstname'],
1309
                'lastname' => $info['lastname'],
1310
                'clicks' => $info['counter'], //+ $clicks[$info['user_id']],
1311
                'ip' => '',
1312
                'timeLoggedIn' => gmdate("H:i:s", strtotime($info['logout_course_date']) - strtotime($info['login_course_date'])),
1313
                'session' => $session['name']
1314
            );
1315
        }
1316
1317
        foreach ($return as $key => $info) {
1318
            //Search for ip, we do less querys if we iterate the final array
1319
            $sql = sprintf("SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date < '%s' ORDER BY login_date DESC LIMIT 1", $info['user_id'], $info['logindate']); //TODO add select by user too
1320
            $result = Database::query($sql);
1321
            $ip = Database::fetch_assoc($result);
1322
            //if no ip founded, we search the closest higher ip
1323
            if (empty($ip['user_ip'])) {
1324
                $sql = sprintf("SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date > '%s'  ORDER BY login_date ASC LIMIT 1", $info['user_id'], $info['logindate']); //TODO add select by user too
1325
                $result = Database::query($sql);
1326
                $ip = Database::fetch_assoc($result);
1327
            }
1328
            #add ip to final array
1329
            $return[$key]['ip'] = $ip['user_ip'];
1330
        }
1331
1332
        return $return;
1333
    }
1334
1335
    /**
1336
     * Creates a new course code based in given code
1337
     *
1338
     * @param string	$session_name
1339
     * <code>
1340
     * $wanted_code = 'curse' if there are in the DB codes like curse1 curse2 the function will return: course3
1341
     * if the course code doest not exist in the DB the same course code will be returned
1342
     * </code>
1343
     * @return string	wanted unused code
1344
     */
1345 View Code Duplication
    public static function generateNextSessionName($session_name)
1346
    {
1347
        $session_name_ok = !self::session_name_exists($session_name);
1348
        if (!$session_name_ok) {
1349
            $table = Database::get_main_table(TABLE_MAIN_SESSION);
1350
            $session_name = Database::escape_string($session_name);
1351
            $sql = "SELECT count(*) as count FROM $table
1352
                    WHERE name LIKE '$session_name%'";
1353
            $result = Database::query($sql);
1354
            if (Database::num_rows($result) > 0) {
1355
                $row = Database::fetch_array($result);
1356
                $count = $row['count'] + 1;
1357
                $session_name = $session_name . '_' . $count;
1358
                $result = self::session_name_exists($session_name);
1359
                if (!$result) {
1360
                    return $session_name;
1361
                }
1362
            }
1363
            return false;
1364
        }
1365
1366
        return $session_name;
1367
    }
1368
1369
    /**
1370
     * Edit a session
1371
     * @author Carlos Vargas from existing code
1372
     * @param integer   $id Session primary key
1373
     * @param string    $name
1374
     * @param string    $startDate
1375
     * @param string    $endDate
1376
     * @param string    $displayStartDate
1377
     * @param string    $displayEndDate
1378
     * @param string    $coachStartDate
1379
     * @param string    $coachEndDate
1380
     * @param integer   $coachId
1381
     * @param integer   $sessionCategoryId
1382
     * @param int       $visibility
1383
     * @param string    $description
1384
     * @param int       $showDescription
1385
     * @param int       $duration
1386
     * @param array     $extraFields
1387
     * @param int       $sessionAdminId
1388
     * @param boolean $sendSubscriptionNotification Optional.
1389
     *          Whether send a mail notification to users being subscribed
1390
     * @return mixed
1391
     */
1392
    public static function edit_session(
1393
        $id,
1394
        $name,
1395
        $startDate,
1396
        $endDate,
1397
        $displayStartDate,
1398
        $displayEndDate,
1399
        $coachStartDate,
1400
        $coachEndDate,
1401
        $coachId,
1402
        $sessionCategoryId,
1403
        $visibility,
1404
        $description = null,
1405
        $showDescription = 0,
1406
        $duration = null,
1407
        $extraFields = array(),
1408
        $sessionAdminId = 0,
1409
        $sendSubscriptionNotification = false
1410
    ) {
1411
        $coachId = intval($coachId);
1412
        $sessionCategoryId = intval($sessionCategoryId);
1413
        $visibility = intval($visibility);
1414
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1415
1416
        if (empty($name)) {
1417
            Display::addFlash(
1418
                Display::return_message(get_lang('SessionNameIsRequired'), 'warning')
1419
            );
1420
1421
            return false;
1422
        } elseif (empty($coachId)) {
1423
            Display::addFlash(
1424
                Display::return_message(get_lang('CoachIsRequired'), 'warning')
1425
            );
1426
1427
            return false;
1428
        } elseif (!empty($startDate) && !api_is_valid_date($startDate, 'Y-m-d H:i') && !api_is_valid_date($startDate, 'Y-m-d H:i:s')) {
1429
            Display::addFlash(
1430
                Display::return_message(get_lang('InvalidStartDate'), 'warning')
1431
            );
1432
1433
            return false;
1434
        } elseif (!empty($endDate) && !api_is_valid_date($endDate, 'Y-m-d H:i') && !api_is_valid_date($endDate, 'Y-m-d H:i:s')) {
1435
            Display::addFlash(
1436
                Display::return_message(get_lang('InvalidEndDate'), 'warning')
1437
            );
1438
1439
            return false;
1440
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
1441
            Display::addFlash(
1442
                Display::return_message(get_lang('StartDateShouldBeBeforeEndDate'), 'warning')
1443
            );
1444
1445
            return false;
1446
        } else {
1447
            $sessionInfo = self::get_session_by_name($name);
1448
            $exists = false;
1449
1450
            if (!empty($sessionInfo)) {
1451
                if ($sessionInfo['id'] != $id) {
1452
                    $exists = true;
1453
                }
1454
            }
1455
1456
            if ($exists) {
1457
                Display::addFlash(
1458
                    Display::return_message(get_lang('SessionNameAlreadyExists'), 'warning')
1459
                );
1460
1461
                return false;
1462
            } else {
1463
                $values = [
1464
                    'name' => $name,
1465
                    'duration' => $duration,
1466
                    'id_coach' => $coachId,
1467
                    'description'=> $description,
1468
                    'show_description' => intval($showDescription),
1469
                    'visibility' => $visibility,
1470
                    'send_subscription_notification' => $sendSubscriptionNotification,
1471
                    'access_start_date' => null,
1472
                    'access_end_date' => null,
1473
                    'display_start_date' => null,
1474
                    'display_end_date' => null,
1475
                    'coach_access_start_date' => null,
1476
                    'coach_access_end_date' => null
1477
                ];
1478
1479
                if (!empty($sessionAdminId)) {
1480
                    $values['session_admin_id'] = $sessionAdminId;
1481
                }
1482
1483
                if (!empty($startDate)) {
1484
                    $values['access_start_date'] = api_get_utc_datetime($startDate);
1485
                }
1486
1487
                if (!empty($endDate)) {
1488
                    $values['access_end_date'] = api_get_utc_datetime($endDate);
1489
                }
1490
1491
                if (!empty($displayStartDate)) {
1492
                    $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
1493
                }
1494
1495
                if (!empty($displayEndDate)) {
1496
                    $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
1497
                }
1498
1499
                if (!empty($coachStartDate)) {
1500
                    $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
1501
                }
1502
                if (!empty($coachEndDate)) {
1503
                    $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
1504
                }
1505
1506
                if (!empty($sessionCategoryId)) {
1507
                    $values['session_category_id'] = $sessionCategoryId;
1508
                } else {
1509
                    $values['session_category_id'] = null;
1510
                }
1511
1512
                Database::update(
1513
                    $tbl_session,
1514
                    $values,
1515
                    array('id = ?' => $id)
1516
                );
1517
1518
                if (!empty($extraFields)) {
1519
                    $extraFields['item_id'] = $id;
1520
                    $sessionFieldValue = new ExtraFieldValue('session');
1521
                    $sessionFieldValue->saveFieldValues($extraFields);
1522
                }
1523
1524
                return $id;
1525
            }
1526
        }
1527
    }
1528
1529
    /**
1530
     * Delete session
1531
     * @author Carlos Vargas  from existing code
1532
     * @param	array	$id_checked an array to delete sessions
1533
     * @param   boolean  $from_ws optional, true if the function is called
1534
     * by a webservice, false otherwise.
1535
     * @return	void	Nothing, or false on error
1536
     * */
1537
    public static function delete($id_checked, $from_ws = false)
1538
    {
1539
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1540
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1541
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1542
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1543
        $tbl_url_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
1544
        $tbl_item_properties = Database::get_course_table(TABLE_ITEM_PROPERTY);
1545
        $tbl_student_publication = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1546
        $tbl_student_publication_assignment = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1547
        $ticket = Database::get_main_table(TABLE_TICKET_TICKET);
1548
        $em = Database::getManager();
1549
1550
        $userId = api_get_user_id();
1551
1552
        /** @var \Chamilo\CoreBundle\Entity\Repository\SequenceRepository $repo */
1553
        $repo = Database::getManager()->getRepository('ChamiloCoreBundle:SequenceResource');
1554
        $sequenceResourse = $repo->findRequirementForResource(
1555
            $id_checked,
1556
            \Chamilo\CoreBundle\Entity\SequenceResource::SESSION_TYPE
1557
        );
1558
1559
        if ($sequenceResourse) {
1560
            Display::addFlash(Display::return_message(get_lang('ThereIsASequenceResourceLinkedToThisSessionYouNeedToDeleteItFirst'), 'error'));
1561
            return false;
1562
        }
1563
1564
        if (is_array($id_checked)) {
1565
            foreach ($id_checked as $sessionId) {
1566
                self::delete($sessionId);
1567
            }
1568
        } else {
1569
            $id_checked = intval($id_checked);
1570
        }
1571
1572
        if (SessionManager::allowed($id_checked) && !$from_ws) {
0 ignored issues
show
Bug introduced by
It seems like $id_checked defined by parameter $id_checked on line 1537 can also be of type array; however, SessionManager::allowed() does only seem to accept integer, maybe add an additional type check?

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

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

An additional type check may prevent trouble.

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

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

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

An additional type check may prevent trouble.

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

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

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

An additional type check may prevent trouble.

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

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

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

An additional type check may prevent trouble.

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
2114
        // update the session-course relation to add the users total
2115
        $sql = "UPDATE $tbl_session_rel_course
2116
                SET nbr_users = $nbr_users
2117
                WHERE session_id = $session_id AND c_id = $courseId";
2118
        Database::query($sql);
2119
    }
2120
2121
    /**
2122
     * Unsubscribe user from session
2123
     *
2124
     * @param int Session id
2125
     * @param int User id
2126
     * @return bool True in case of success, false in case of error
2127
     */
2128
    public static function unsubscribe_user_from_session($session_id, $user_id)
2129
    {
2130
        $session_id = (int) $session_id;
2131
        $user_id = (int) $user_id;
2132
2133
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2134
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2135
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2136
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2137
2138
        $sql = "DELETE FROM $tbl_session_rel_user
2139
                WHERE
2140
                    session_id = $session_id AND
2141
                    user_id = $user_id AND
2142
                    relation_type <> " . SESSION_RELATION_TYPE_RRHH . "";
2143
        $result = Database::query($sql);
2144
        $return = Database::affected_rows($result);
2145
2146
        // Update number of users
2147
        $sql = "UPDATE $tbl_session
2148
                SET nbr_users = nbr_users - $return
2149
                WHERE id = $session_id ";
2150
        Database::query($sql);
2151
2152
        // Get the list of courses related to this session
2153
        $course_list = SessionManager::get_course_list_by_session_id($session_id);
2154
2155
        if (!empty($course_list)) {
2156
            foreach ($course_list as $course) {
0 ignored issues
show
Bug introduced by
The expression $course_list of type integer|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

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

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

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

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

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

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

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

Consider the follow example

<?php

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

    return false;
}

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

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

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

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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

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

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

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

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

Loading history...
5537
     *
5538
     * @return array|int
5539
     */
5540
    public static function getCountUserTracking(
5541
        $keyword = null,
5542
        $active = null,
5543
        $lastConnectionDate = null,
5544
        $sessionIdList = array(),
5545
        $studentIdList = array(),
5546
        $filterUserStatus = null
5547
    ) {
5548
        $userId = api_get_user_id();
5549
        $drhLoaded = false;
5550
5551
        if (api_is_drh()) {
5552
            if (api_drh_can_access_all_session_content()) {
5553
                $count = self::getAllUsersFromCoursesFromAllSessionFromStatus(
5554
                    'drh_all',
5555
                    $userId,
5556
                    true,
5557
                    null,
5558
                    null,
5559
                    null,
5560
                    null,
5561
                    $keyword,
5562
                    $active,
5563
                    $lastConnectionDate,
5564
                    $sessionIdList,
5565
                    $studentIdList,
5566
                    $filterUserStatus
5567
                );
5568
                $drhLoaded = true;
5569
            }
5570
        }
5571
5572
        if ($drhLoaded == false) {
5573
            $count = UserManager::getUsersFollowedByUser(
5574
                $userId,
5575
                $filterUserStatus,
5576
                false,
5577
                false,
5578
                true,
5579
                null,
5580
                null,
5581
                null,
5582
                null,
5583
                $active,
5584
                $lastConnectionDate,
5585
                api_is_student_boss() ? STUDENT_BOSS : COURSEMANAGER,
5586
                $keyword
5587
            );
5588
        }
5589
5590
        return $count;
5591
    }
5592
5593
    /**
5594
     * Get teachers followed by a user
5595
     * @param int $userId
5596
     * @param int $active
5597
     * @param string $lastConnectionDate
5598
     * @param bool $getCount
5599
     * @param array $sessionIdList
5600
     * @return array|int
5601
     */
5602
    public static function getTeacherTracking(
5603
        $userId,
5604
        $active = 1,
5605
        $lastConnectionDate = null,
5606
        $getCount = false,
5607
        $sessionIdList = array()
5608
    ) {
5609
        $teacherListId = array();
5610
5611
        if (api_is_drh() || api_is_platform_admin()) {
5612
            // Followed teachers by drh
5613
            if (api_drh_can_access_all_session_content()) {
5614
                if (empty($sessionIdList)) {
5615
                    $sessions = SessionManager::get_sessions_followed_by_drh($userId);
5616
                    $sessionIdList = array();
5617
                    foreach ($sessions as $session) {
5618
                        $sessionIdList[] = $session['id'];
5619
                    }
5620
                }
5621
5622
                $sessionIdList = array_map('intval', $sessionIdList);
5623
                $sessionToString = implode("', '",  $sessionIdList);
5624
5625
                $course = Database::get_main_table(TABLE_MAIN_COURSE);
5626
                $sessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
5627
                $courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5628
5629
                // Select the teachers.
5630
                $sql = "SELECT DISTINCT(cu.user_id) FROM $course c
5631
                        INNER JOIN $sessionCourse src ON c.id = src.c_id
5632
                        INNER JOIN $courseUser cu ON (cu.c_id = c.id)
5633
		                WHERE src.session_id IN ('$sessionToString') AND cu.status = 1";
5634
                $result = Database::query($sql);
5635
                while($row = Database::fetch_array($result, 'ASSOC')) {
5636
                    $teacherListId[$row['user_id']] = $row['user_id'];
5637
                }
5638
            } else {
5639
                $teacherResult = UserManager::get_users_followed_by_drh($userId, COURSEMANAGER);
5640
                foreach ($teacherResult as $userInfo) {
5641
                    $teacherListId[] = $userInfo['user_id'];
5642
                }
5643
            }
5644
        }
5645
5646
        if (!empty($teacherListId)) {
5647
            $tableUser = Database::get_main_table(TABLE_MAIN_USER);
5648
5649
            $select = "SELECT DISTINCT u.* ";
5650
            if ($getCount) {
5651
                $select = "SELECT count(DISTINCT(u.user_id)) as count";
5652
            }
5653
5654
            $sql = "$select FROM $tableUser u";
5655
5656
            if (!empty($lastConnectionDate)) {
5657
                $tableLogin = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
5658
                //$sql .= " INNER JOIN $tableLogin l ON (l.login_user_id = u.user_id) ";
5659
            }
5660
            $active = intval($active);
5661
            $teacherListId = implode("','", $teacherListId);
5662
            $where = " WHERE u.active = $active AND u.user_id IN ('$teacherListId') ";
5663
5664
            if (!empty($lastConnectionDate)) {
5665
                $lastConnectionDate = Database::escape_string($lastConnectionDate);
5666
                //$where .= " AND l.login_date <= '$lastConnectionDate' ";
5667
            }
5668
5669
            $sql .= $where;
5670
            $result = Database::query($sql);
5671 View Code Duplication
            if (Database::num_rows($result)) {
5672
                if ($getCount) {
5673
                    $row = Database::fetch_array($result);
5674
                    return $row['count'];
5675
                } else {
5676
5677
                    return Database::store_result($result, 'ASSOC');
5678
                }
5679
            }
5680
        }
5681
5682
        return 0;
5683
    }
5684
5685
    /**
5686
     * Get the list of course tools that have to be dealt with in case of
5687
     * registering any course to a session
5688
     * @return array The list of tools to be dealt with (literal names)
5689
     */
5690
    public static function getCourseToolToBeManaged()
5691
    {
5692
        return array(
5693
            'courseDescription',
5694
            'courseIntroduction',
5695
        );
5696
    }
5697
5698
    /**
5699
     * Calls the methods bound to each tool when a course is registered into a session
5700
     * @param int $sessionId
5701
     * @param int $courseId
5702
     * @return void
5703
     */
5704 View Code Duplication
    public static function installCourse($sessionId, $courseId)
5705
    {
5706
        return true;
5707
        $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...
5708
5709
        foreach ($toolList as $tool) {
5710
            $method = 'add' . $tool;
5711
            if (method_exists(get_class(), $method)) {
5712
                self::$method($sessionId, $courseId);
5713
            }
5714
        }
5715
    }
5716
5717
    /**
5718
     * Calls the methods bound to each tool when a course is unregistered from
5719
     * a session
5720
     * @param int $sessionId
5721
     * @param int $courseId
5722
     */
5723 View Code Duplication
    public static function unInstallCourse($sessionId, $courseId)
5724
    {
5725
        return true;
5726
        $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...
5727
5728
        foreach ($toolList as $tool) {
5729
            $method = 'remove' . $tool;
5730
            if (method_exists(get_class(), $method)) {
5731
                self::$method($sessionId, $courseId);
5732
            }
5733
        }
5734
    }
5735
5736
    /**
5737
     * @param int $sessionId
5738
     * @param int $courseId
5739
     */
5740 View Code Duplication
    public static function addCourseIntroduction($sessionId, $courseId)
5741
    {
5742
        // @todo create a tool intro lib
5743
        $sessionId = intval($sessionId);
5744
        $courseId = intval($courseId);
5745
5746
        $TBL_INTRODUCTION = Database::get_course_table(TABLE_TOOL_INTRO);
5747
        $sql = "SELECT * FROM $TBL_INTRODUCTION WHERE c_id = $courseId";
5748
        $result = Database::query($sql);
5749
        $result = Database::store_result($result, 'ASSOC');
0 ignored issues
show
Bug introduced by
It seems like $result can be null; however, store_result() does not accept null, maybe add an additional type check?

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
8074
            // for each category of session
8075
            $htmlCatSessions = '';
8076
            foreach ($listCoursesInfo['sessionCatList'] as $j => $listCatSessionsInfo) {
8077
                // we got an array of session categories
8078
                $catSessionId = $listCoursesInfo['sessionCatList'][$j]['catSessionId'];
8079
                $catSessionName = $listCoursesInfo['sessionCatList'][$j]['catSessionName'];
8080
8081
                $listParamsCatSession['icon'] = Display::return_icon('folder_blue.png', $catSessionName, array(), ICON_SIZE_LARGE);
8082
                $listParamsCatSession['link'] = '';
8083
                $listParamsCatSession['title'] = $catSessionName;
8084
8085
                $marginShift = 20;
8086
                if ($catSessionName != '') {
8087
                    $htmlCatSessions .= '<div style="margin-left:'.$marginShift.'px;">' .
8088
                        CourseManager::course_item_html($listParamsCatSession, true) . '</div>';
0 ignored issues
show
Bug introduced by
The method course_item_html() does not exist on CourseManager. Did you maybe mean course_item_html_no_icon()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
8089
                    $marginShift = 40;
8090
                }
8091
8092
                // for each sessions
8093
                $listCatSessionSessionList = $listCoursesInfo['sessionCatList'][$j]['sessionList'];
8094
                $htmlSession = '';
8095
                foreach ($listCatSessionSessionList as $k => $listSessionInfo) {
8096
                    // we got an array of session info
8097
                    $sessionId = $listSessionInfo['sessionId'];
8098
                    $sessionName = $listSessionInfo['sessionName'];
8099
8100
                    $listParamsSession['icon'] = Display::return_icon('blackboard_blue.png', $sessionName, array(), ICON_SIZE_LARGE);
8101
                    $listParamsSession['link'] = '';
8102
                    $linkToCourseSession = $courseInfo['course_public_url'].'?id_session='.$sessionId;
8103
                    $listParamsSession['title'] =
8104
                        $sessionName.'<div style="font-weight:normal; font-style:italic">
8105
                            <a href="'.$linkToCourseSession.'">'.get_lang('GoToCourseInsideSession').'</a>
8106
                            </div>';
8107
                    $htmlSession .= '<div style="margin-left:'.$marginShift.'px;">'.
8108
                        CourseManager::course_item_html($listParamsSession, true).'</div>';
0 ignored issues
show
Bug introduced by
The method course_item_html() does not exist on CourseManager. Did you maybe mean course_item_html_no_icon()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
8109
                }
8110
                $htmlCatSessions .= $htmlSession;
8111
            }
8112
            $htmlRes .= $htmlCourse.'<div style="display:none" id="course-'.$courseCode.'">'.$htmlCatSessions.'</div></div>';
8113
        }
8114
8115
        return $htmlRes;
8116
    }
8117
8118
    /**
8119
     * @param int $userId
8120
     * @param int $courseId
8121
     *
8122
     * @return array
8123
     */
8124 View Code Duplication
    public static function searchCourseInSessionsFromUser($userId, $courseId)
8125
    {
8126
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
8127
        $userId = (int) $userId;
8128
        $courseId = (int) $courseId;
8129
        if (empty($userId) || empty($courseId)) {
8130
            return [];
8131
        }
8132
8133
        $sql = "SELECT * FROM $table 
8134
                WHERE c_id = $courseId AND user_id = $userId";
8135
        $result = Database::query($sql);
8136
8137
        return Database::store_result($result, 'ASSOC');
8138
    }
8139
}
8140