Completed
Push — master ( 27e209...a08afa )
by Julito
186:04 queued 150:53
created

SessionManager::edit_session()   F

Complexity

Conditions 24
Paths 1544

Size

Total Lines 139
Code Lines 80

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 24
eloc 80
nc 1544
nop 17
dl 0
loc 139
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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. Consider defining an alias.

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

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

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

// Bar.php
namespace OtherDir;

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

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

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

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

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
7
use Chamilo\CoreBundle\Entity\Session;
8
use Chamilo\CoreBundle\Entity\SequenceResource;
9
use Chamilo\CoreBundle\Entity\SessionRelUser;
10
use Chamilo\CoreBundle\Entity\Course;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Course. Consider defining an alias.

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...
11
use Chamilo\UserBundle\Entity\User;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, User. Consider defining an alias.

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...
12
use Chamilo\CoreBundle\Entity\Repository\SequenceRepository;
13
14
/**
15
 * Class SessionManager
16
 *
17
 * This is the session library for Chamilo
18
 * (as in courses>session, not as in PHP session)
19
 * All main sessions functions should be placed here.
20
 * This class provides methods for sessions management.
21
 * Include/require it in your code to use its features.
22
 *
23
 * @package chamilo.library
24
 *
25
 */
26
class SessionManager
27
{
28
    public static $_debug = false;
29
30
    /**
31
     * Constructor
32
     */
33
    public function __construct()
34
    {
35
    }
36
37
    /**
38
     * Fetches a session from the database
39
     * @param  int $id Session Id
40
     *
41
     * @return  array   Session details
42
     */
43
    public static function fetch($id)
44
    {
45
        $em = Database::getManager();
46
47
        if (empty($id)) {
48
            return [];
49
        }
50
51
        /** @var Session $session */
52
        $session = $em->find('ChamiloCoreBundle:Session', $id);
53
54
        if (!$session) {
55
            return [];
56
        }
57
58
        $result = [
59
            'id' => $session->getId(),
60
            'id_coach' => $session->getGeneralCoach() ? $session->getGeneralCoach()->getId() : null,
61
            'session_category_id' => $session->getCategory() ? $session->getCategory()->getId() : null,
62
            'name' => $session->getName(),
63
            'description' => $session->getDescription(),
64
            'show_description' => $session->getShowDescription(),
65
            'duration' => $session->getDuration(),
66
            'nbr_courses' => $session->getNbrCourses(),
67
            'nbr_users' => $session->getNbrUsers(),
68
            'nbr_classes' => $session->getNbrClasses(),
69
            'session_admin_id' => $session->getSessionAdminId(),
70
            'visibility' => $session->getVisibility(),
71
            'promotion_id' => $session->getPromotionId(),
72
            'display_start_date' => $session->getDisplayStartDate()
73
                ? $session->getDisplayStartDate()->format('Y-m-d H:i:s')
74
                : null,
75
            'display_end_date' => $session->getDisplayEndDate()
76
                ? $session->getDisplayEndDate()->format('Y-m-d H:i:s')
77
                : null,
78
            'access_start_date' => $session->getAccessStartDate()
79
                ? $session->getAccessStartDate()->format('Y-m-d H:i:s')
80
                : null,
81
            'access_end_date' => $session->getAccessEndDate()
82
                ? $session->getAccessEndDate()->format('Y-m-d H:i:s')
83
                : null,
84
            'coach_access_start_date' => $session->getCoachAccessStartDate()
85
                ? $session->getCoachAccessStartDate()->format('Y-m-d H:i:s')
86
                : null,
87
            'coach_access_end_date' => $session->getCoachAccessEndDate()
88
                ? $session->getCoachAccessEndDate()->format('Y-m-d H:i:s')
89
                : null,
90
            'send_subscription_notification' => $session->getSendSubscriptionNotification(),
91
        ];
92
93
        return $result;
94
    }
95
96
    /**
97
     * Create a session
98
     * @author Carlos Vargas <[email protected]>, from existing code
99
     * @param   string  $name
100
     * @param   string  $startDate (YYYY-MM-DD hh:mm:ss)
101
     * @param   string  $endDate (YYYY-MM-DD hh:mm:ss)
102
     * @param   string  $displayStartDate (YYYY-MM-DD hh:mm:ss)
103
     * @param   string  $displayEndDate (YYYY-MM-DD hh:mm:ss)
104
     * @param   string  $coachStartDate (YYYY-MM-DD hh:mm:ss)
105
     * @param   string  $coachEndDate (YYYY-MM-DD hh:mm:ss)
106
     * @param   integer $sessionCategoryId ID of the session category in which this session is registered
107
     * @param   mixed   $coachId If integer, this is the session coach id, if string, the coach ID will be looked for from the user table
108
     * @param   integer $visibility Visibility after end date (0 = read-only, 1 = invisible, 2 = accessible)
109
     * @param   bool    $fixSessionNameIfExists
110
     * @param   string  $duration
111
     * @param   string  $description Optional. The session description
112
     * @param   int     $showDescription Optional. Whether show the session description
113
     * @param   array   $extraFields
114
     * @param   int     $sessionAdminId Optional. If this sessions was created by a session admin, assign it to him
115
     * @param boolean $sendSubscriptionNotification Optional.
116
     *          Whether send a mail notification to users being subscribed
117
     * @todo use an array to replace all this parameters or use the model.lib.php ...
118
     * @return mixed       Session ID on success, error message otherwise
119
     * */
120
    public static function create_session(
121
        $name,
122
        $startDate,
123
        $endDate,
124
        $displayStartDate,
125
        $displayEndDate,
126
        $coachStartDate,
127
        $coachEndDate,
128
        $coachId,
129
        $sessionCategoryId,
130
        $visibility = 1,
131
        $fixSessionNameIfExists = false,
132
        $duration = null,
133
        $description = null,
134
        $showDescription = 0,
135
        $extraFields = [],
136
        $sessionAdminId = 0,
137
        $sendSubscriptionNotification = false
138
    ) {
139
        global $_configuration;
140
141
        //Check portal limits
142
        $access_url_id = 1;
143
144
        if (api_get_multiple_access_url()) {
145
            $access_url_id = api_get_current_access_url_id();
146
        }
147
148
        if (is_array($_configuration[$access_url_id]) &&
149
            isset($_configuration[$access_url_id]['hosting_limit_sessions']) &&
150
            $_configuration[$access_url_id]['hosting_limit_sessions'] > 0
151
        ) {
152
            $num = self::count_sessions();
153
            if ($num >= $_configuration[$access_url_id]['hosting_limit_sessions']) {
154
                api_warn_hosting_contact('hosting_limit_sessions');
155
                return get_lang('PortalSessionsLimitReached');
156
            }
157
        }
158
159
        $name = Database::escape_string(trim($name));
160
        $sessionCategoryId = intval($sessionCategoryId);
161
        $visibility = intval($visibility);
162
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
163
164
        $startDate = Database::escape_string($startDate);
165
        $endDate = Database::escape_string($endDate);
166
167
        if (empty($name)) {
168
            $msg = get_lang('SessionNameIsRequired');
169
            return $msg;
170
        } elseif (!empty($startDate) && !api_is_valid_date($startDate, 'Y-m-d H:i') && !api_is_valid_date($startDate, 'Y-m-d H:i:s')) {
171
            $msg = get_lang('InvalidStartDate');
172
            return $msg;
173
        } elseif (!empty($endDate) && !api_is_valid_date($endDate, 'Y-m-d H:i') && !api_is_valid_date($endDate, 'Y-m-d H:i:s')) {
174
            $msg = get_lang('InvalidEndDate');
175
            return $msg;
176
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
177
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
178
            return $msg;
179
        } else {
180
            $ready_to_create = false;
181
            if ($fixSessionNameIfExists) {
182
                $name = self::generateNextSessionName($name);
183
                if ($name) {
184
                    $ready_to_create = true;
185
                } else {
186
                    $msg = get_lang('SessionNameAlreadyExists');
187
                    return $msg;
188
                }
189
            } else {
190
                $rs = Database::query("SELECT 1 FROM $tbl_session WHERE name='".$name."'");
191
                if (Database::num_rows($rs)) {
192
                    $msg = get_lang('SessionNameAlreadyExists');
193
                    return $msg;
194
                }
195
                $ready_to_create = true;
196
            }
197
198
            if ($ready_to_create) {
199
                $sessionAdminId = !empty($sessionAdminId) ? $sessionAdminId : api_get_user_id();
200
                $values = [
201
                    'name' => $name,
202
                    'id_coach' => $coachId,
203
                    'session_admin_id' => $sessionAdminId,
204
                    'visibility' => $visibility,
205
                    'description' => $description,
206
                    'show_description' => intval($showDescription),
207
                    'send_subscription_notification' => (int) $sendSubscriptionNotification,
208
                ];
209
210
                if (!empty($startDate)) {
211
                    $values['access_start_date'] = api_get_utc_datetime($startDate);
212
                }
213
214
                if (!empty($endDate)) {
215
                    $values['access_end_date'] = api_get_utc_datetime($endDate);
216
                }
217
218
                if (!empty($displayStartDate)) {
219
                    $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
220
                }
221
222
                if (!empty($displayEndDate)) {
223
                    $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
224
                }
225
226
                if (!empty($coachStartDate)) {
227
                    $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
228
                }
229
                if (!empty($coachEndDate)) {
230
                    $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
231
                }
232
233
                if (!empty($sessionCategoryId)) {
234
                    $values['session_category_id'] = $sessionCategoryId;
235
                }
236
237
                $session_id = Database::insert($tbl_session, $values);
238
239
                $duration = intval($duration);
240
241
                if (!empty($duration)) {
242
                    $sql = "UPDATE $tbl_session SET
243
                        access_start_date = NULL,
244
                        access_end_date = NULL,
245
                        display_start_date = NULL,
246
                        display_end_date = NULL,
247
                        coach_access_start_date = NULL,
248
                        coach_access_end_date = NULL,
249
                        duration = $duration
250
                    WHERE id = $session_id";
251
                    Database::query($sql);
252
                } else {
253
                    $sql = "UPDATE $tbl_session
254
                        SET duration = 0
255
                        WHERE id = $session_id";
256
                    Database::query($sql);
257
                }
258
259
                if (!empty($session_id)) {
260
                    $extraFields['item_id'] = $session_id;
261
262
                    $sessionFieldValue = new ExtraFieldValue('session');
263
                    $sessionFieldValue->saveFieldValues($extraFields);
264
265
                    /*
266
                      Sends a message to the user_id = 1
267
268
                      $user_info = api_get_user_info(1);
269
                      $complete_name = $user_info['firstname'].' '.$user_info['lastname'];
270
                      $subject = api_get_setting('siteName').' - '.get_lang('ANewSessionWasCreated');
271
                      $message = get_lang('ANewSessionWasCreated')." <br /> ".get_lang('NameOfTheSession').' : '.$name;
272
                      api_mail_html($complete_name, $user_info['email'], $subject, $message);
273
                     *
274
                     */
275
                    //Adding to the correct URL
276
                    $access_url_id = api_get_current_access_url_id();
277
                    UrlManager::add_session_to_url($session_id, $access_url_id);
278
279
                    // add event to system log
280
                    $user_id = api_get_user_id();
281
                    Event::addEvent(
282
                        LOG_SESSION_CREATE,
283
                        LOG_SESSION_ID,
284
                        $session_id,
285
                        api_get_utc_datetime(),
286
                        $user_id
287
                    );
288
                }
289
290
                return $session_id;
291
            }
292
        }
293
    }
294
295
    /**
296
     * @param string $name
297
     *
298
     * @return bool
299
     */
300
    public static function sessionNameExists($name)
301
    {
302
        $name = Database::escape_string($name);
303
        $sql = "SELECT COUNT(*) as count FROM ".Database::get_main_table(TABLE_MAIN_SESSION)."
304
                WHERE name = '$name'";
305
        $result = Database::fetch_array(Database::query($sql));
306
307
        return $result['count'] > 0;
308
    }
309
310
    /**
311
     * @param string $where_condition
312
     *
313
     * @return mixed
314
     */
315
    public static function get_count_admin($where_condition = '')
316
    {
317
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
318
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
319
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
320
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
321
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
322
323
        $where = 'WHERE 1=1 ';
324
        $user_id = api_get_user_id();
325
        $extraJoin = '';
326
327
        if (api_is_session_admin() &&
328
            api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
329
        ) {
330
            $where .= " AND (
331
                            s.session_admin_id = $user_id  OR
332
                            sru.user_id = '$user_id' AND
333
                            sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."'
334
                            )
335
                      ";
336
337
            $extraJoin = " INNER JOIN $tbl_session_rel_user sru
338
                           ON sru.session_id = s.id ";
339
        }
340
341
        $today = api_get_utc_datetime();
342
        $today = api_strtotime($today, 'UTC');
343
        $today = date('Y-m-d', $today);
344
345
        if (!empty($where_condition)) {
346
            $where_condition = str_replace("(  session_active = ':'  )", '1=1', $where_condition);
347
348
            $where_condition = str_replace('category_name', 'sc.name', $where_condition);
349
            $where_condition = str_replace(
350
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
351
                [') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 "],
352
                $where_condition
353
            );
354
            $where_condition = str_replace(
355
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
356
                [') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "],
357
                $where_condition
358
            );
359
        } else {
360
            $where_condition = " AND 1 = 1";
361
        }
362
363
        $courseCondition = null;
364
        if (strpos($where_condition, 'c.id')) {
365
            $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
366
            $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
367
            $courseCondition = " INNER JOIN $table course_rel_session
368
                                 ON (s.id = course_rel_session.session_id)
369
                                 INNER JOIN $tableCourse c
370
                                 ON (course_rel_session.c_id = c.id)
371
                                ";
372
        }
373
374
        $sql = "SELECT COUNT(id) as total_rows FROM (
375
                SELECT DISTINCT
376
                 IF (
377
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
378
                    (s.access_start_date IS NULL AND s.access_end_date  = IS NULL ) OR
379
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
380
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
381
				, 1, 0) as session_active,
382
                s.id
383
                FROM $tbl_session s
384
                LEFT JOIN $tbl_session_category sc
385
                ON s.session_category_id = sc.id
386
                INNER JOIN $tbl_user u
387
                ON s.id_coach = u.user_id
388
                $courseCondition
389
                $extraJoin
390
                $where $where_condition ) as session_table";
391
392
        if (api_is_multiple_url_enabled()) {
393
            $access_url_id = api_get_current_access_url_id();
394
            if ($access_url_id != -1) {
395
                $where .= " AND ar.access_url_id = $access_url_id ";
396
397
                $sql = "SELECT count(id) as total_rows FROM (
398
                SELECT DISTINCT
399
                  IF (
400
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
401
                    (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
402
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
403
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
404
				, 1, 0)
405
				as session_active,
406
				s.id
407
                FROM $tbl_session s
408
                    LEFT JOIN  $tbl_session_category sc
409
                    ON s.session_category_id = sc.id
410
                    INNER JOIN $tbl_user u ON s.id_coach = u.user_id
411
                    INNER JOIN $table_access_url_rel_session ar
412
                    ON ar.session_id = s.id
413
                    $courseCondition
414
                    $extraJoin
415
                $where $where_condition) as session_table";
416
            }
417
        }
418
419
        $result_rows = Database::query($sql);
420
        $row = Database::fetch_array($result_rows);
421
        $num = $row['total_rows'];
422
423
        return $num;
424
    }
425
426
    /**
427
     * Gets the admin session list callback of the session/session_list.php page
428
     * @param array $options order and limit keys
429
     * @param boolean $get_count Whether to get all the results or only the count
430
     * @param array $columns
431
     * @param array $extraFieldsToLoad
432
     *
433
     * @return mixed Integer for number of rows, or array of results
434
     * @assert ([],true) !== false
435
     */
436
    public static function get_sessions_admin(
437
        $options = [],
438
        $get_count = false,
439
        $columns = [],
440
        $extraFieldsToLoad = []
441
    ) {
442
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
443
        $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
444
445
        $where = 'WHERE 1 = 1 ';
446
        $user_id = api_get_user_id();
447
448
        if (!api_is_platform_admin()) {
449
            if (api_is_session_admin() &&
450
                api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
451
            ) {
452
                $where .= " AND s.session_admin_id = $user_id ";
453
            }
454
        }
455
456
        if (!api_is_platform_admin() &&
457
            api_is_teacher() &&
458
            api_get_setting('allow_teachers_to_create_sessions') == 'true'
459
        ) {
460
            $where .= " AND s.id_coach = $user_id ";
461
        }
462
        $extra_field = new ExtraFieldModel('session');
463
        $conditions = $extra_field->parseConditions($options);
464
        $inject_joins = $conditions['inject_joins'];
465
        $where .= $conditions['where'];
466
        $inject_where = $conditions['inject_where'];
467
        $inject_extra_fields = $conditions['inject_extra_fields'];
468
        $order = $conditions['order'];
469
        $limit = $conditions['limit'];
470
471
        $isMakingOrder = false;
472
        $showCountUsers = false;
473
474
        if ($get_count == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
475
            $select = " SELECT count(DISTINCT s.id) as total_rows";
476
        } else {
477
            if (!empty($columns['column_model'])) {
478
                foreach ($columns['column_model'] as $column) {
479
                    if ($column['name'] == 'users') {
480
                        $showCountUsers = true;
481
                    }
482
                }
483
            }
484
485
            $select =
486
                "SELECT DISTINCT 
487
                     s.name,
488
                     s.display_start_date, 
489
                     s.display_end_date, 
490
                     access_start_date, 
491
                     access_end_date, 
492
                     s.visibility, 
493
                     s.session_category_id, 
494
                     $inject_extra_fields 
495
                     s.id 
496
             ";
497
498
            if ($showCountUsers) {
499
                $select .= ', count(su.user_id) users';
500
            }
501
            if (isset($options['order'])) {
502
                $isMakingOrder = strpos($options['order'], 'category_name') === 0;
503
            }
504
        }
505
506
        $isFilteringSessionCategory = strpos($where, 'category_name') !== false;
507
        $isFilteringSessionCategoryWithName = strpos($where, 'sc.name') !== false;
508
509
        if ($isMakingOrder || $isFilteringSessionCategory || $isFilteringSessionCategoryWithName) {
510
            $inject_joins .= " LEFT JOIN $sessionCategoryTable sc ON s.session_category_id = sc.id ";
511
512
            if ($isFilteringSessionCategory) {
513
                $where = str_replace('category_name', 'sc.name', $where);
514
            }
515
516
            if ($isMakingOrder) {
517
                $order = str_replace('category_name', 'sc.name', $order);
518
            }
519
        }
520
521
        if ($showCountUsers) {
522
            $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
523
            //$tableUserUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
524
            $inject_joins .= " LEFT JOIN $table su ON (su.session_id = s.id)";
525
        }
526
527
        $query = "$select FROM $tbl_session s $inject_joins $where $inject_where";
528
529
        if (api_is_multiple_url_enabled()) {
530
            $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
531
            $access_url_id = api_get_current_access_url_id();
532
            if ($access_url_id != -1) {
533
                $where .= " AND ar.access_url_id = $access_url_id ";
534
                $query = "$select
535
                        FROM $tbl_session s $inject_joins
536
                        INNER JOIN $table_access_url_rel_session ar
537
                        ON (ar.session_id = s.id) $where";
538
            }
539
        }
540
541
        if ($showCountUsers) {
542
            $query .= ' GROUP by s.id';
543
        }
544
        $allowOrder = api_get_configuration_value('session_list_order');
545
        if ($allowOrder) {
546
            $order = ' ORDER BY position ASC';
547
        }
548
549
        $query .= $order;
550
        $query .= $limit;
551
        $result = Database::query($query);
552
553
        $categories = self::get_all_session_category();
554
        $orderedCategories = [];
555
        if (!empty($categories)) {
556
            foreach ($categories as $category) {
557
                $orderedCategories[$category['id']] = $category['name'];
558
            }
559
        }
560
        $formatted_sessions = [];
561
        if (Database::num_rows($result)) {
562
            $sessions = Database::store_result($result, 'ASSOC');
563
            if ($get_count) {
564
                return $sessions[0]['total_rows'];
565
            }
566
567
            $activeIcon = Display::return_icon(
568
                'accept.png',
569
                get_lang('Active'),
570
                [],
571
                ICON_SIZE_SMALL
572
            );
573
            $inactiveIcon = Display::return_icon(
574
                'error.png',
575
                get_lang('Inactive'),
576
                [],
577
                ICON_SIZE_SMALL
578
            );
579
580
            foreach ($sessions as $session) {
581
                $session_id = $session['id'];
582
                if ($showCountUsers) {
583
                    $session['users'] = SessionManager::get_users_by_session(
584
                        $session['id'],
585
                        null,
586
                        true
587
                    );
588
                }
589
                $url = api_get_path(WEB_CODE_PATH)."session/resume_session.php?id_session=".$session['id'];
590
                if (api_is_drh()) {
591
                    $url = api_get_path(WEB_CODE_PATH)."session/about.php?session_id=".$session['id'];
592
                }
593
                if (api_is_platform_admin()) {
594
                    $url = api_get_path(WEB_CODE_PATH)."session/resume_session.php?id_session=".$session['id'];
595
                }
596
597
                if ($extraFieldsToLoad) {
598
                    $url = api_get_path(WEB_CODE_PATH)."session/about.php?session_id=".$session['id'];
599
                }
600
                $session['name'] = Display::url(
601
                    $session['name'],
602
                    $url
603
                );
604
605
                if (!empty($extraFieldsToLoad)) {
606
                    foreach ($extraFieldsToLoad as $field) {
607
                        $extraFieldValue = new ExtraFieldValue('session');
608
                        $fieldData = $extraFieldValue->getAllValuesByItemAndField(
609
                            $session['id'],
610
                            $field['id']
611
                        );
612
                        $fieldDataArray = [];
613
                        $fieldDataToString = '';
614
                        if (!empty($fieldData)) {
615
                            foreach ($fieldData as $data) {
616
                                $fieldDataArray[] = $data['value'];
617
                            }
618
                            $fieldDataToString = implode(', ', $fieldDataArray);
619
                        }
620
                        $session[$field['variable']] = $fieldDataToString;
621
                    }
622
                }
623
624
                if (isset($session['session_active']) && $session['session_active'] == 1) {
625
                    $session['session_active'] = $activeIcon;
626
                } else {
627
                    $session['session_active'] = $inactiveIcon;
628
                }
629
630
                $session = self::convert_dates_to_local($session, true);
631
632
                switch ($session['visibility']) {
633
                    case SESSION_VISIBLE_READ_ONLY: //1
634
                        $session['visibility'] = get_lang('ReadOnly');
635
                        break;
636
                    case SESSION_VISIBLE:           //2
637
                    case SESSION_AVAILABLE:         //4
638
                        $session['visibility'] = get_lang('Visible');
639
                        break;
640
                    case SESSION_INVISIBLE:         //3
641
                        $session['visibility'] = api_ucfirst(get_lang('Invisible'));
642
                        break;
643
                }
644
645
                // Cleaning double selects.
646
                foreach ($session as $key => &$value) {
647
                    if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $options_by_double does not exist. Did you maybe mean $options?
Loading history...
648
                        $options = explode('::', $value);
649
                    }
650
                    $original_key = $key;
651
652
                    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...
653
                    } else {
654
                        $key = str_replace('_second', '', $key);
655
                    }
656
657
                    if (isset($options_by_double[$key])) {
658
                        if (isset($options[0])) {
659
                            if (isset($options_by_double[$key][$options[0]])) {
660
                                if (strpos($original_key, '_second') === false) {
661
                                    $value = $options_by_double[$key][$options[0]]['option_display_text'];
662
                                } else {
663
                                    $value = $options_by_double[$key][$options[1]]['option_display_text'];
664
                                }
665
                            }
666
                        }
667
                    }
668
                }
669
                $formatted_sessions[$session_id] = $session;
670
                $categoryName = isset($orderedCategories[$session['session_category_id']]) ? $orderedCategories[$session['session_category_id']] : '';
671
                $formatted_sessions[$session_id]['category_name'] = $categoryName;
672
            }
673
        }
674
675
        return $formatted_sessions;
676
    }
677
678
    /**
679
     *  Get total of records for progress of learning paths in the given session
680
     *  @param int session id
681
     *  @return int
682
     */
683
    public static function get_count_session_lp_progress($sessionId = 0)
684
    {
685
        $tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
686
        $tbl_lp_view = Database::get_course_table(TABLE_LP_VIEW);
687
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
688
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
689
690
        $sessionId = intval($sessionId);
691
692
        $sql = "SELECT  count(*) as total_rows
693
                FROM $tbl_lp_view v
694
                INNER JOIN $tbl_lp l ON l.id = v.lp_id
695
                INNER JOIN $tbl_user u ON u.user_id = v.user_id
696
                INNER JOIN $tbl_course c
697
                WHERE v.session_id = ".$sessionId;
698
        $result_rows = Database::query($sql);
699
        $row = Database::fetch_array($result_rows);
700
        $num = $row['total_rows'];
701
702
        return $num;
703
    }
704
705
    /**
706
     * Gets the progress of learning paths in the given session
707
     * @param int   $sessionId
708
     * @param int $courseId
709
     * @param string $date_from
710
     * @param string $date_to
711
     * @param array options order and limit keys
712
     * @return array table with user name, lp name, progress
713
     */
714
    public static function get_session_lp_progress(
715
        $sessionId = 0,
716
        $courseId = 0,
717
        $date_from,
718
        $date_to,
719
        $options
720
    ) {
721
        //escaping vars
722
        $sessionId = $sessionId == 'T' ? 'T' : intval($sessionId);
723
        $courseId = intval($courseId);
724
        $date_from = Database::escape_string($date_from);
725
        $date_to = Database::escape_string($date_to);
726
727
        //tables
728
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
729
        $user = Database::get_main_table(TABLE_MAIN_USER);
730
        $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
731
732
        $course = api_get_course_info_by_id($courseId);
733
734
        //getting all the students of the course
735
        //we are not using this because it only returns user ids
736
        /* if (empty($sessionId)
737
          {
738
          // Registered students in a course outside session.
739
          $users = CourseManager::get_student_list_from_course_code($course_code);
740
          } else {
741
          // Registered students in session.
742
          $users = CourseManager::get_student_list_from_course_code($course_code, true, $sessionId);
743
          } */
744
745
        $sessionCond = 'and session_id = %s';
746
        if ($sessionId == 'T') {
747
            $sessionCond = '';
748
        }
749
750
        $where = " WHERE c_id = '%s' AND s.status <> 2 $sessionCond";
751
752
        $limit = null;
753
        if (!empty($options['limit'])) {
754
            $limit = " LIMIT ".$options['limit'];
755
        }
756
757
        if (!empty($options['where'])) {
758
            $where .= ' '.$options['where'];
759
        }
760
761
        $order = null;
762
        if (!empty($options['order'])) {
763
            $order = " ORDER BY ".$options['order'];
764
        }
765
766
        $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
767
                FROM $session_course_user s
768
                INNER JOIN $user u ON u.user_id = s.user_id
769
                $where
770
                $order
771
                $limit";
772
773
        $sql_query = sprintf($sql, Database::escape_string($course['real_id']), $sessionId);
774
775
        $rs = Database::query($sql_query);
776
        while ($user = Database::fetch_array($rs)) {
777
            $users[$user['user_id']] = $user;
778
        }
779
780
        // Get lessons
781
        $lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
0 ignored issues
show
Bug introduced by
It seems like $sessionId can also be of type string; however, parameter $session_id of LearnpathList::get_course_lessons() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

781
        $lessons = LearnpathList::get_course_lessons($course['code'], /** @scrutinizer ignore-type */ $sessionId);
Loading history...
782
783
        $table = [];
784
        foreach ($users as $user) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $users does not seem to be defined for all execution paths leading up to this point.
Loading history...
785
            $data = [
786
                'lastname' => $user[1],
787
                'firstname' => $user[2],
788
                'username' => $user[3],
789
            ];
790
791
            $sessionCond = 'AND v.session_id = %d';
792
            if ($sessionId == 'T') {
793
                $sessionCond = "";
794
            }
795
796
            //Get lessons progress by user
797
            $sql = "SELECT v.lp_id as id, v.progress
798
                    FROM  $tbl_course_lp_view v
799
                    WHERE v.c_id = %d
800
                    AND v.user_id = %d
801
            $sessionCond";
802
803
            $sql_query = sprintf(
804
                $sql,
805
                intval($courseId),
806
                intval($user['user_id']),
807
                $sessionId
808
            );
809
810
            $result = Database::query($sql_query);
811
812
            $user_lessons = [];
813
            while ($row = Database::fetch_array($result)) {
814
                $user_lessons[$row['id']] = $row;
815
            }
816
817
            //Match course lessons with user progress
818
            $progress = 0;
819
            $count = 0;
820
            foreach ($lessons as $lesson) {
821
                $data[$lesson['id']] = (!empty($user_lessons[$lesson['id']]['progress'])) ? $user_lessons[$lesson['id']]['progress'] : 0;
822
                $progress += $data[$lesson['id']];
823
                $data[$lesson['id']] = $data[$lesson['id']].'%';
824
                $count++;
825
            }
826
            if ($count == 0) {
827
                $data['total'] = 0;
828
            } else {
829
                $data['total'] = round($progress / $count, 2).'%';
830
            }
831
            $table[] = $data;
832
        }
833
834
        return $table;
835
    }
836
837
    /**
838
     * Gets the survey answers
839
     * @param int   $sessionId
840
     * @param int   $courseId
841
     * @param int   $surveyId
842
     * @param array options order and limit keys
843
     * @todo fix the query
844
     * @return array table with user name, lp name, progress
845
     */
846
    public static function get_survey_overview(
847
        $sessionId = 0,
848
        $courseId = 0,
849
        $surveyId = 0,
850
        $date_from,
851
        $date_to,
852
        $options
853
    ) {
854
        //escaping vars
855
        $sessionId = intval($sessionId);
856
        $courseId = intval($courseId);
857
        $surveyId = intval($surveyId);
858
859
        //tables
860
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
861
        $user = Database::get_main_table(TABLE_MAIN_USER);
862
        $c_survey = Database::get_course_table(TABLE_SURVEY);
863
        $c_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
864
        $c_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
865
        $c_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
866
867
        $course = api_get_course_info_by_id($courseId);
868
869
        $where = " WHERE c_id = '%s' AND s.status <> 2 AND session_id = %s";
870
871
        $limit = null;
872
        if (!empty($options['limit'])) {
873
            $limit = " LIMIT ".$options['limit'];
874
        }
875
876
        if (!empty($options['where'])) {
877
            $where .= ' '.$options['where'];
878
        }
879
880
        $order = null;
881
        if (!empty($options['order'])) {
882
            $order = " ORDER BY ".$options['order'];
883
        }
884
885
        $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
886
                FROM $session_course_user s
887
                INNER JOIN $user u ON u.user_id = s.user_id
888
                $where $order $limit";
889
890
        $sql_query = sprintf($sql, intval($course['real_id']), $sessionId);
891
        $rs = Database::query($sql_query);
892
        while ($user = Database::fetch_array($rs)) {
893
            $users[$user['user_id']] = $user;
894
        }
895
896
        //Get survey questions
897
        $questions = SurveyManager::get_questions($surveyId, $courseId);
898
899
        //Survey is anonymous?
900
        $result = Database::query(sprintf("SELECT anonymous FROM $c_survey WHERE survey_id = %d", $surveyId));
901
        $row = Database::fetch_array($result);
902
        $anonymous = ($row['anonymous'] == 1) ? true : false;
903
904
        $table = [];
905
        foreach ($users as $user) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $users does not seem to be defined for all execution paths leading up to this point.
Loading history...
906
            $data = [
907
                'lastname' => ($anonymous ? '***' : $user[1]),
908
                'firstname' => ($anonymous ? '***' : $user[2]),
909
                'username' => ($anonymous ? '***' : $user[3]),
910
            ];
911
912
            //Get questions by user
913
            $sql = "SELECT sa.question_id, sa.option_id, sqo.option_text, sq.type
914
                    FROM $c_survey_answer sa
915
                    INNER JOIN $c_survey_question sq
916
                    ON sq.question_id = sa.question_id
917
                    LEFT JOIN $c_survey_question_option sqo
918
                    ON
919
                      sqo.c_id = sa.c_id AND
920
                      sqo.question_id = sq.question_id AND
921
                      sqo.question_option_id = sa.option_id AND
922
                      sqo.survey_id = sq.survey_id
923
                    WHERE
924
                      sa.survey_id = %d AND
925
                      sa.c_id = %d AND
926
                      sa.user = %d
927
            "; //. $where_survey;
928
            $sql_query = sprintf($sql, $surveyId, $courseId, $user['user_id']);
929
930
            $result = Database::query($sql_query);
931
932
            $user_questions = [];
933
            while ($row = Database::fetch_array($result)) {
934
                $user_questions[$row['question_id']] = $row;
935
            }
936
937
            //Match course lessons with user progress
938
            foreach ($questions as $question_id => $question) {
939
                $option_text = 'option_text';
940
                if ($user_questions[$question_id]['type'] == 'open') {
941
                    $option_text = 'option_id';
942
                }
943
                $data[$question_id] = $user_questions[$question_id][$option_text];
944
            }
945
946
            $table[] = $data;
947
        }
948
        return $table;
949
    }
950
951
    /**
952
     * Gets the progress of the given session
953
     * @param int   $sessionId
954
     * @param int   $courseId
955
     * @param array options order and limit keys
956
     *
957
     * @return array table with user name, lp name, progress
958
     */
959
    public static function get_session_progress(
960
        $sessionId,
961
        $courseId,
962
        $date_from,
963
        $date_to,
964
        $options
965
    ) {
966
        $sessionId = intval($sessionId);
967
968
        $getAllSessions = false;
969
        if (empty($sessionId)) {
970
            $sessionId = 0;
971
            $getAllSessions = true;
972
        }
973
974
        //tables
975
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
976
        $user = Database::get_main_table(TABLE_MAIN_USER);
977
        $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
978
        $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
979
        $tbl_course_lp = Database::get_course_table(TABLE_LP_MAIN);
980
        $wiki = Database::get_course_table(TABLE_WIKI);
981
        $table_stats_default = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
982
        $table_stats_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
983
984
        $course = api_get_course_info_by_id($courseId);
985
        $where = " WHERE c_id = '%s' AND s.status <> 2 ";
986
987
        $limit = null;
988
        if (!empty($options['limit'])) {
989
            $limit = " LIMIT ".$options['limit'];
990
        }
991
992
        if (!empty($options['where'])) {
993
            $where .= ' '.$options['where'];
994
        }
995
996
        $order = null;
997
        if (!empty($options['order'])) {
998
            $order = " ORDER BY ".$options['order'];
999
        }
1000
1001
        //TODO, fix create report without session
1002
        $queryVariables = [$course['real_id']];
1003
        if (!empty($sessionId)) {
1004
            $where .= ' AND session_id = %s';
1005
            $queryVariables[] = $sessionId;
1006
            $sql = "SELECT
1007
                        u.user_id, u.lastname, u.firstname, u.username,
1008
                        u.email, s.c_id, s.session_id
1009
                    FROM $session_course_user s
1010
                    INNER JOIN $user u
1011
                    ON u.user_id = s.user_id
1012
                    $where $order $limit";
1013
        } else {
1014
            $sql = "SELECT
1015
                        u.user_id, u.lastname, u.firstname, u.username,
1016
                        u.email, s.c_id, s.session_id
1017
                    FROM $session_course_user s
1018
                    INNER JOIN $user u ON u.user_id = s.user_id
1019
                    $where $order $limit";
1020
        }
1021
1022
        $sql_query = vsprintf($sql, $queryVariables);
1023
        $rs = Database::query($sql_query);
1024
        while ($user = Database::fetch_array($rs)) {
1025
            $users[$user['user_id']] = $user;
1026
        }
1027
1028
        /**
1029
         *  Lessons
1030
         */
1031
        $sql = "SELECT * FROM $tbl_course_lp WHERE c_id = %s "; //AND session_id = %s
1032
        $sql_query = sprintf($sql, $course['real_id']);
1033
        $result = Database::query($sql_query);
1034
        $arrLesson = [[]];
1035
        while ($row = Database::fetch_array($result)) {
1036
            if (empty($arrLesson[$row['session_id']]['lessons_total'])) {
1037
                $arrLesson[$row['session_id']]['lessons_total'] = 1;
1038
            } else {
1039
                $arrLesson[$row['session_id']]['lessons_total']++;
1040
            }
1041
        }
1042
1043
        /**
1044
         *  Exercises
1045
         */
1046
        $exercises = ExerciseLib::get_all_exercises(
1047
            $course,
1048
            $sessionId,
1049
            false,
1050
            '',
1051
            $getAllSessions
1052
        );
1053
        $exercises_total = count($exercises);
1054
1055
        /**
1056
         *  Assignments
1057
         */
1058
        //total
1059
        $params = [$course['real_id']];
1060
        if ($getAllSessions) {
1061
            $sql = "SELECT count(w.id) as count
1062
                    FROM $workTable w
1063
                    LEFT JOIN $workTableAssignment a
1064
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
1065
                    WHERE 
1066
                        w.c_id = %s AND 
1067
                        parent_id = 0 AND 
1068
                        active IN (1, 0)";
1069
        } else {
1070
            $sql = "SELECT count(w.id) as count
1071
                    FROM $workTable w
1072
                    LEFT JOIN $workTableAssignment a
1073
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
1074
                    WHERE 
1075
                        w.c_id = %s AND 
1076
                        parent_id = 0 AND 
1077
                        active IN (1, 0)";
1078
1079
            if (empty($sessionId)) {
1080
                $sql .= ' AND w.session_id = NULL ';
1081
            } else {
1082
                $sql .= ' AND w.session_id = %s ';
1083
                $params[] = $sessionId;
1084
            }
1085
        }
1086
1087
        $sql_query = vsprintf($sql, $params);
1088
        $result = Database::query($sql_query);
1089
        $row = Database::fetch_array($result);
1090
        $assignments_total = $row['count'];
1091
1092
        /**
1093
         * Wiki
1094
         */
1095
        if ($getAllSessions) {
1096
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
1097
                    WHERE c_id = %s";
1098
        } else {
1099
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
1100
                    WHERE c_id = %s and session_id = %s";
1101
        }
1102
        $sql_query = sprintf($sql, $course['real_id'], $sessionId);
1103
        $result = Database::query($sql_query);
1104
        $row = Database::fetch_array($result);
1105
        $wiki_total = $row['count'];
1106
1107
        /**
1108
         * Surveys
1109
         */
1110
        $survey_user_list = [];
1111
        $survey_list = SurveyManager::get_surveys($course['code'], $sessionId);
1112
1113
        $surveys_total = count($survey_list);
1114
        foreach ($survey_list as $survey) {
1115
            $user_list = SurveyManager::get_people_who_filled_survey(
1116
                $survey['survey_id'],
1117
                false,
1118
                $course['real_id']
1119
            );
1120
            foreach ($user_list as $user_id) {
1121
                isset($survey_user_list[$user_id]) ? $survey_user_list[$user_id]++ : $survey_user_list[$user_id] = 1;
1122
            }
1123
        }
1124
1125
        /**
1126
         * Forums
1127
         */
1128
        $forums_total = CourseManager::getCountForum(
1129
            $course['real_id'],
1130
            $sessionId,
1131
            $getAllSessions
1132
        );
1133
1134
        //process table info
1135
        foreach ($users as $user) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $users does not seem to be defined for all execution paths leading up to this point.
Loading history...
1136
            //Course description
1137
            $sql = "SELECT count(*) as count
1138
                    FROM $table_stats_access
1139
                    WHERE access_tool = 'course_description'
1140
                    AND c_id = '%s'
1141
                    AND access_session_id = %s
1142
                    AND access_user_id = %s ";
1143
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1144
1145
            $result = Database::query($sql_query);
1146
            $row = Database::fetch_array($result);
1147
            $course_description_progress = ($row['count'] > 0) ? 100 : 0;
1148
1149
            if (!empty($arrLesson[$user['id_session']]['lessons_total'])) {
1150
                $lessons_total = $arrLesson[$user['id_session']]['lessons_total'];
1151
            } else {
1152
                $lessons_total = !empty($arrLesson[0]['lessons_total']) ? $arrLesson[0]['lessons_total'] : 0;
1153
            }
1154
1155
            //Lessons
1156
            //TODO: Lessons done and left is calculated by progress per item in lesson, maybe we should calculate it only per completed lesson?
1157
            $lessons_progress = Tracking::get_avg_student_progress(
1158
                $user['user_id'],
1159
                $course['code'],
1160
                [],
1161
                $user['id_session']
1162
            );
1163
            $lessons_done = ($lessons_progress * $lessons_total) / 100;
1164
            $lessons_left = $lessons_total - $lessons_done;
1165
1166
            // Exercises
1167
            $exercises_progress = str_replace(
1168
                '%',
1169
                '',
1170
                Tracking::get_exercise_student_progress(
1171
                    $exercises,
1172
                    $user['user_id'],
1173
                    $course['real_id'],
1174
                    $user['id_session']
1175
                )
1176
            );
1177
            $exercises_done = round(($exercises_progress * $exercises_total) / 100);
1178
            $exercises_left = $exercises_total - $exercises_done;
1179
1180
            //Assignments
1181
            $assignments_done = Tracking::count_student_assignments($user['user_id'], $course['code'], $user['id_session']);
1182
            $assignments_left = $assignments_total - $assignments_done;
1183
            if (!empty($assignments_total)) {
1184
                $assignments_progress = round((($assignments_done * 100) / $assignments_total), 2);
1185
            } else {
1186
                $assignments_progress = 0;
1187
            }
1188
1189
            // Wiki
1190
            // total revisions per user
1191
            $sql = "SELECT count(*) as count
1192
                    FROM $wiki
1193
                    WHERE c_id = %s and session_id = %s and user_id = %s";
1194
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1195
            $result = Database::query($sql_query);
1196
            $row = Database::fetch_array($result);
1197
            $wiki_revisions = $row['count'];
1198
            //count visited wiki pages
1199
            $sql = "SELECT count(distinct default_value) as count
1200
                    FROM $table_stats_default
1201
                    WHERE
1202
                        default_user_id = %s AND
1203
                        default_event_type = 'wiki_page_view' AND
1204
                        default_value_type = 'wiki_page_id' AND
1205
                        c_id = %s
1206
                    ";
1207
            $sql_query = sprintf($sql, $user['user_id'], $course['real_id']);
1208
            $result = Database::query($sql_query);
1209
            $row = Database::fetch_array($result);
1210
1211
            $wiki_read = $row['count'];
1212
            $wiki_unread = $wiki_total - $wiki_read;
1213
            if (!empty($wiki_total)) {
1214
                $wiki_progress = round((($wiki_read * 100) / $wiki_total), 2);
1215
            } else {
1216
                $wiki_progress = 0;
1217
            }
1218
1219
            //Surveys
1220
            $surveys_done = (isset($survey_user_list[$user['user_id']]) ? $survey_user_list[$user['user_id']] : 0);
1221
            $surveys_left = $surveys_total - $surveys_done;
1222
            if (!empty($surveys_total)) {
1223
                $surveys_progress = round((($surveys_done * 100) / $surveys_total), 2);
1224
            } else {
1225
                $surveys_progress = 0;
1226
            }
1227
1228
            //Forums
1229
            $forums_done = CourseManager::getCountForumPerUser(
1230
                $user['user_id'],
1231
                $course['real_id'],
1232
                $user['id_session']
1233
            );
1234
            $forums_left = $forums_total - $forums_done;
1235
            if (!empty($forums_total)) {
1236
                $forums_progress = round((($forums_done * 100) / $forums_total), 2);
1237
            } else {
1238
                $forums_progress = 0;
1239
            }
1240
1241
            // Overall Total
1242
            $overall_total = ($course_description_progress + $exercises_progress + $forums_progress + $assignments_progress + $wiki_progress + $surveys_progress) / 6;
1243
1244
            $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>';
1245
            $linkForum = '<a href="'.api_get_path(WEB_CODE_PATH).'forum/index.php?cidReq='.$course['code'].'&id_session='.$user['id_session'].'"> %s </a>';
1246
            $linkWork = '<a href="'.api_get_path(WEB_CODE_PATH).'work/work.php?cidReq='.$course['code'].'&id_session='.$user['id_session'].'"> %s </a>';
1247
            $linkWiki = '<a href="'.api_get_path(WEB_CODE_PATH).'wiki/index.php?cidReq='.$course['code'].'&session_id='.$user['id_session'].'&action=statistics"> %s </a>';
1248
            $linkSurvey = '<a href="'.api_get_path(WEB_CODE_PATH).'survey/survey_list.php?cidReq='.$course['code'].'&id_session='.$user['id_session'].'"> %s </a>';
1249
1250
            $table[] = [
1251
                'lastname' => $user[1],
1252
                'firstname' => $user[2],
1253
                'username' => $user[3],
1254
                #'profile'   => '',
1255
                'total' => round($overall_total, 2).'%',
1256
                'courses' => sprintf($link, $course_description_progress.'%'),
1257
                'lessons' => sprintf($link, $lessons_progress.'%'),
1258
                'exercises' => sprintf($link, $exercises_progress.'%'),
1259
                'forums' => sprintf($link, $forums_progress.'%'),
1260
                'homeworks' => sprintf($link, $assignments_progress.'%'),
1261
                'wikis' => sprintf($link, $wiki_progress.'%'),
1262
                'surveys' => sprintf($link, $surveys_progress.'%'),
1263
                //course description
1264
                'course_description_progress' => $course_description_progress.'%',
1265
                //lessons
1266
                'lessons_total' => sprintf($link, $lessons_total),
1267
                'lessons_done' => sprintf($link, $lessons_done),
1268
                'lessons_left' => sprintf($link, $lessons_left),
1269
                'lessons_progress' => sprintf($link, $lessons_progress.'%'),
1270
                //exercises
1271
                'exercises_total' => sprintf($link, $exercises_total),
1272
                'exercises_done' => sprintf($link, $exercises_done),
1273
                'exercises_left' => sprintf($link, $exercises_left),
1274
                'exercises_progress' => sprintf($link, $exercises_progress.'%'),
1275
                //forums
1276
                'forums_total' => sprintf($linkForum, $forums_total),
1277
                'forums_done' => sprintf($linkForum, $forums_done),
1278
                'forums_left' => sprintf($linkForum, $forums_left),
1279
                'forums_progress' => sprintf($linkForum, $forums_progress.'%'),
1280
                //assignments
1281
                'assignments_total' => sprintf($linkWork, $assignments_total),
1282
                'assignments_done' => sprintf($linkWork, $assignments_done),
1283
                'assignments_left' => sprintf($linkWork, $assignments_left),
1284
                'assignments_progress' => sprintf($linkWork, $assignments_progress.'%'),
1285
                //wiki
1286
                'wiki_total' => sprintf($linkWiki, $wiki_total),
1287
                'wiki_revisions' => sprintf($linkWiki, $wiki_revisions),
1288
                'wiki_read' => sprintf($linkWiki, $wiki_read),
1289
                'wiki_unread' => sprintf($linkWiki, $wiki_unread),
1290
                'wiki_progress' => sprintf($linkWiki, $wiki_progress.'%'),
1291
                //survey
1292
                'surveys_total' => sprintf($linkSurvey, $surveys_total),
1293
                'surveys_done' => sprintf($linkSurvey, $surveys_done),
1294
                'surveys_left' => sprintf($linkSurvey, $surveys_left),
1295
                'surveys_progress' => sprintf($linkSurvey, $surveys_progress.'%'),
1296
            ];
1297
        }
1298
1299
        return $table;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $table seems to be defined by a foreach iteration on line 1135. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
1300
    }
1301
1302
    /**
1303
     * Get the ip, total of clicks, login date and time logged in for all user, in one session
1304
     * @todo track_e_course_access table should have ip so we dont have to look for it in track_e_login
1305
     *
1306
     * @author César Perales <[email protected]>, Beeznest Team
1307
     * @version 1.9.6
1308
     */
1309
    public static function get_user_data_access_tracking_overview(
1310
        $sessionId,
1311
        $courseId,
1312
        $studentId = 0,
1313
        $profile = '',
1314
        $date_from = '',
1315
        $date_to = '',
1316
        $options
1317
    ) {
1318
        //escaping variables
1319
        $sessionId = intval($sessionId);
1320
        $courseId = intval($courseId);
1321
        $studentId = intval($studentId);
1322
        $profile = intval($profile);
1323
        $date_from = Database::escape_string($date_from);
1324
        $date_to = Database::escape_string($date_to);
1325
1326
        // database table definition
1327
        $user = Database::get_main_table(TABLE_MAIN_USER);
1328
        $course = Database::get_main_table(TABLE_MAIN_COURSE);
1329
        $track_e_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
1330
        $track_e_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1331
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
1332
1333
        global $export_csv;
1334
        if ($export_csv) {
1335
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
1336
        } else {
1337
            $is_western_name_order = api_is_western_name_order();
1338
        }
1339
1340
        $where = null;
1341
        if (isset($sessionId) && !empty($sessionId)) {
1342
            $where = sprintf(" WHERE a.session_id = %d", $sessionId);
1343
        }
1344
        if (isset($courseId) && !empty($courseId)) {
1345
            $where .= sprintf(" AND c.id = %d", $courseId);
1346
        }
1347
        if (isset($studentId) && !empty($studentId)) {
1348
            $where .= sprintf(" AND u.user_id = %d", $studentId);
1349
        }
1350
        if (isset($profile) && !empty($profile)) {
1351
            $where .= sprintf(" AND u.status = %d", $profile);
1352
        }
1353
        if (!empty($date_to) && !empty($date_from)) {
1354
            $where .= sprintf(
1355
                " AND a.login_course_date >= '%s 00:00:00'
1356
                 AND a.login_course_date <= '%s 23:59:59'",
1357
                $date_from,
1358
                $date_to
1359
            );
1360
        }
1361
1362
        $limit = null;
1363
        if (!empty($options['limit'])) {
1364
            $limit = " LIMIT ".$options['limit'];
1365
        }
1366
1367
        if (!empty($options['where'])) {
1368
            $where .= ' '.$options['where'];
1369
        }
1370
1371
        $order = null;
1372
        if (!empty($options['order'])) {
1373
            $order = " ORDER BY ".$options['order'];
1374
        }
1375
1376
        //TODO add course name
1377
        $sql = "SELECT
1378
                a.login_course_date ,
1379
                u.username ,
1380
                " . ($is_western_name_order ? "
1381
                    u.firstname,
1382
                    u.lastname,
1383
                    " : "
1384
                    u.lastname,
1385
                    u.firstname,
1386
                ")."
1387
                a.logout_course_date,
1388
                a.counter,
1389
                c.title,
1390
                c.code,
1391
                u.user_id,
1392
                a.session_id
1393
            FROM $track_e_course_access a
1394
            INNER JOIN $user u ON a.user_id = u.user_id
1395
            INNER JOIN $course c ON a.c_id = c.id
1396
            $where $order $limit";
1397
        $result = Database::query(sprintf($sql, $sessionId, $courseId));
1398
1399
        $data = [];
1400
        while ($user = Database::fetch_assoc($result)) {
1401
            $data[] = $user;
1402
        }
1403
1404
        foreach ($data as $key => $info) {
1405
            $sql = "SELECT
1406
                    name
1407
                    FROM $sessionTable
1408
                    WHERE
1409
                    id = {$info['session_id']}";
1410
            $result = Database::query($sql);
1411
            $session = Database::fetch_assoc($result);
1412
1413
            // building array to display
1414
            $return[] = [
1415
                'user_id' => $info['user_id'],
1416
                'logindate' => $info['login_course_date'],
1417
                'username' => $info['username'],
1418
                'firstname' => $info['firstname'],
1419
                'lastname' => $info['lastname'],
1420
                'clicks' => $info['counter'], //+ $clicks[$info['user_id']],
1421
                'ip' => '',
1422
                'timeLoggedIn' => gmdate("H:i:s", strtotime($info['logout_course_date']) - strtotime($info['login_course_date'])),
1423
                'session' => $session['name'],
1424
            ];
1425
        }
1426
1427
        foreach ($return as $key => $info) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $return seems to be defined by a foreach iteration on line 1404. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
1428
            //Search for ip, we do less querys if we iterate the final array
1429
            $sql = sprintf(
1430
                "SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date < '%s' ORDER BY login_date DESC LIMIT 1",
1431
                $info['user_id'],
1432
                $info['logindate']
1433
            ); //TODO add select by user too
1434
            $result = Database::query($sql);
1435
            $ip = Database::fetch_assoc($result);
1436
            //if no ip founded, we search the closest higher ip
1437
            if (empty($ip['user_ip'])) {
1438
                $sql = sprintf(
1439
                    "SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date > '%s'  ORDER BY login_date ASC LIMIT 1",
1440
                    $info['user_id'],
1441
                    $info['logindate']
1442
                ); //TODO add select by user too
1443
                $result = Database::query($sql);
1444
                $ip = Database::fetch_assoc($result);
1445
            }
1446
            #add ip to final array
1447
            $return[$key]['ip'] = $ip['user_ip'];
1448
        }
1449
1450
        return $return;
1451
    }
1452
1453
    /**
1454
     * Creates a new course code based in given code
1455
     *
1456
     * @param string $session_name
1457
     * <code>
1458
     * $wanted_code = 'curse' if there are in the DB codes like curse1 curse2 the function will return: course3
1459
     * if the course code doest not exist in the DB the same course code will be returned
1460
     * </code>
1461
     * @return string wanted unused code
1462
     */
1463
    public static function generateNextSessionName($session_name)
1464
    {
1465
        $session_name_ok = !self::sessionNameExists($session_name);
1466
        if (!$session_name_ok) {
1467
            $table = Database::get_main_table(TABLE_MAIN_SESSION);
1468
            $session_name = Database::escape_string($session_name);
1469
            $sql = "SELECT count(*) as count FROM $table
1470
                    WHERE name LIKE '$session_name%'";
1471
            $result = Database::query($sql);
1472
            if (Database::num_rows($result) > 0) {
1473
                $row = Database::fetch_array($result);
1474
                $count = $row['count'] + 1;
1475
                $session_name = $session_name.'_'.$count;
1476
                $result = self::sessionNameExists($session_name);
1477
                if (!$result) {
1478
                    return $session_name;
1479
                }
1480
            }
1481
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
1482
        }
1483
1484
        return $session_name;
1485
    }
1486
1487
    /**
1488
     * Edit a session
1489
     * @author Carlos Vargas from existing code
1490
     * @param integer   $id Session primary key
1491
     * @param string    $name
1492
     * @param string    $startDate
1493
     * @param string    $endDate
1494
     * @param string    $displayStartDate
1495
     * @param string    $displayEndDate
1496
     * @param string    $coachStartDate
1497
     * @param string    $coachEndDate
1498
     * @param integer   $coachId
1499
     * @param integer   $sessionCategoryId
1500
     * @param int       $visibility
1501
     * @param string    $description
1502
     * @param int       $showDescription
1503
     * @param int       $duration
1504
     * @param array     $extraFields
1505
     * @param int       $sessionAdminId
1506
     * @param boolean $sendSubscriptionNotification Optional.
1507
     *          Whether send a mail notification to users being subscribed
1508
     * @return mixed
1509
     */
1510
    public static function edit_session(
1511
        $id,
1512
        $name,
1513
        $startDate,
1514
        $endDate,
1515
        $displayStartDate,
1516
        $displayEndDate,
1517
        $coachStartDate,
1518
        $coachEndDate,
1519
        $coachId,
1520
        $sessionCategoryId,
1521
        $visibility,
1522
        $description = null,
1523
        $showDescription = 0,
1524
        $duration = null,
1525
        $extraFields = [],
1526
        $sessionAdminId = 0,
1527
        $sendSubscriptionNotification = false
1528
    ) {
1529
        $coachId = intval($coachId);
1530
        $sessionCategoryId = intval($sessionCategoryId);
1531
        $visibility = intval($visibility);
1532
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1533
1534
        if (empty($name)) {
1535
            Display::addFlash(
1536
                Display::return_message(get_lang('SessionNameIsRequired'), 'warning')
1537
            );
1538
1539
            return false;
1540
        } elseif (empty($coachId)) {
1541
            Display::addFlash(
1542
                Display::return_message(get_lang('CoachIsRequired'), 'warning')
1543
            );
1544
1545
            return false;
1546
        } elseif (!empty($startDate) &&
1547
            !api_is_valid_date($startDate, 'Y-m-d H:i') &&
1548
            !api_is_valid_date($startDate, 'Y-m-d H:i:s')
1549
        ) {
1550
            Display::addFlash(
1551
                Display::return_message(get_lang('InvalidStartDate'), 'warning')
1552
            );
1553
1554
            return false;
1555
        } elseif (!empty($endDate) &&
1556
            !api_is_valid_date($endDate, 'Y-m-d H:i') &&
1557
            !api_is_valid_date($endDate, 'Y-m-d H:i:s')
1558
        ) {
1559
            Display::addFlash(
1560
                Display::return_message(get_lang('InvalidEndDate'), 'warning')
1561
            );
1562
1563
            return false;
1564
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
1565
            Display::addFlash(
1566
                Display::return_message(get_lang('StartDateShouldBeBeforeEndDate'), 'warning')
1567
            );
1568
1569
            return false;
1570
        } else {
1571
            $sessionInfo = self::get_session_by_name($name);
1572
            $exists = false;
1573
1574
            if (!empty($sessionInfo)) {
1575
                if ($sessionInfo['id'] != $id) {
1576
                    $exists = true;
1577
                }
1578
            }
1579
1580
            if ($exists) {
1581
                Display::addFlash(
1582
                    Display::return_message(get_lang('SessionNameAlreadyExists'), 'warning')
1583
                );
1584
1585
                return false;
1586
            } else {
1587
                $values = [
1588
                    'name' => $name,
1589
                    'duration' => $duration,
1590
                    'id_coach' => $coachId,
1591
                    'description'=> $description,
1592
                    'show_description' => intval($showDescription),
1593
                    'visibility' => $visibility,
1594
                    'send_subscription_notification' => $sendSubscriptionNotification,
1595
                    'access_start_date' => null,
1596
                    'access_end_date' => null,
1597
                    'display_start_date' => null,
1598
                    'display_end_date' => null,
1599
                    'coach_access_start_date' => null,
1600
                    'coach_access_end_date' => null,
1601
                ];
1602
1603
                if (!empty($sessionAdminId)) {
1604
                    $values['session_admin_id'] = $sessionAdminId;
1605
                }
1606
1607
                if (!empty($startDate)) {
1608
                    $values['access_start_date'] = api_get_utc_datetime($startDate);
1609
                }
1610
1611
                if (!empty($endDate)) {
1612
                    $values['access_end_date'] = api_get_utc_datetime($endDate);
1613
                }
1614
1615
                if (!empty($displayStartDate)) {
1616
                    $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
1617
                }
1618
1619
                if (!empty($displayEndDate)) {
1620
                    $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
1621
                }
1622
1623
                if (!empty($coachStartDate)) {
1624
                    $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
1625
                }
1626
                if (!empty($coachEndDate)) {
1627
                    $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
1628
                }
1629
1630
                if (!empty($sessionCategoryId)) {
1631
                    $values['session_category_id'] = $sessionCategoryId;
1632
                } else {
1633
                    $values['session_category_id'] = null;
1634
                }
1635
1636
                Database::update(
1637
                    $tbl_session,
1638
                    $values,
1639
                    ['id = ?' => $id]
1640
                );
1641
1642
                if (!empty($extraFields)) {
1643
                    $extraFields['item_id'] = $id;
1644
                    $sessionFieldValue = new ExtraFieldValue('session');
1645
                    $sessionFieldValue->saveFieldValues($extraFields);
1646
                }
1647
1648
                return $id;
1649
            }
1650
        }
1651
    }
1652
1653
    /**
1654
     * Delete session
1655
     * @author Carlos Vargas  from existing code
1656
     * @param array $id_checked an array to delete sessions
1657
     * @param boolean $from_ws optional, true if the function is called
1658
     * by a webservice, false otherwise.
1659
     * @return bool
1660
     * */
1661
    public static function delete($id_checked, $from_ws = false)
1662
    {
1663
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1664
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1665
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1666
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1667
        $tbl_url_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
1668
        $tbl_item_properties = Database::get_course_table(TABLE_ITEM_PROPERTY);
1669
        $tbl_student_publication = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1670
        $tbl_student_publication_assignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1671
        $userGroupSessionTable = Database::get_main_table(TABLE_USERGROUP_REL_SESSION);
1672
        $trackCourseAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1673
        $trackAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
1674
1675
        $ticket = Database::get_main_table(TABLE_TICKET_TICKET);
1676
        $em = Database::getManager();
1677
        $userId = api_get_user_id();
1678
1679
        /** @var SequenceRepository $repo */
1680
        $repo = Database::getManager()->getRepository('ChamiloCoreBundle:SequenceResource');
1681
        $sequenceResource = $repo->findRequirementForResource(
1682
            $id_checked,
1683
            SequenceResource::SESSION_TYPE
1684
        );
1685
1686
        if ($sequenceResource) {
1687
            Display::addFlash(
1688
                Display::return_message(
1689
                    get_lang('ThereIsASequenceResourceLinkedToThisSessionYouNeedToDeleteItFirst'),
1690
                    'error'
1691
                )
1692
            );
1693
            return false;
1694
        }
1695
1696
        if (is_array($id_checked)) {
1697
            foreach ($id_checked as $sessionId) {
1698
                self::delete($sessionId);
1699
            }
1700
        } else {
1701
            $id_checked = intval($id_checked);
1702
        }
1703
1704
        if (self::allowed($id_checked) && !$from_ws) {
1705
            $qb = $em
1706
                ->createQuery('
1707
                    SELECT s.sessionAdminId FROM ChamiloCoreBundle:Session s
1708
                    WHERE s.id = ?1
1709
                ')
1710
                ->setParameter(1, $id_checked);
1711
1712
            $res = $qb->getSingleScalarResult();
1713
1714
            if ($res != $userId && !api_is_platform_admin()) {
1715
                api_not_allowed(true);
1716
            }
1717
        }
1718
1719
        // Delete documents inside a session
1720
        $courses = self::getCoursesInSession($id_checked);
1721
        foreach ($courses as $courseId) {
1722
            $courseInfo = api_get_course_info_by_id($courseId);
1723
            DocumentManager::deleteDocumentsFromSession($courseInfo, $id_checked);
1724
            $works = Database::select(
1725
                '*',
1726
                $tbl_student_publication,
1727
                [
1728
                    'where' => ['session_id = ? AND c_id = ?' => [$id_checked, $courseId]],
1729
                ]
1730
            );
1731
1732
            $currentCourseRepositorySys = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/';
1733
            foreach ($works as $index => $work) {
1734
                if ($work['filetype'] = 'folder') {
1735
                    Database::query("DELETE FROM $tbl_student_publication_assignment WHERE publication_id = $index");
1736
                }
1737
                my_delete($currentCourseRepositorySys.'/'.$work['url']);
1738
            }
1739
        }
1740
1741
        // Class
1742
        $sql = "DELETE FROM $userGroupSessionTable
1743
                WHERE session_id IN($id_checked)";
1744
        Database::query($sql);
1745
1746
        Database::query("DELETE FROM $tbl_student_publication WHERE session_id IN($id_checked)");
1747
        Database::query("DELETE FROM $tbl_session_rel_course WHERE session_id IN($id_checked)");
1748
        Database::query("DELETE FROM $tbl_session_rel_course_rel_user WHERE session_id IN($id_checked)");
1749
        Database::query("DELETE FROM $tbl_session_rel_user WHERE session_id IN($id_checked)");
1750
        Database::query("DELETE FROM $tbl_item_properties WHERE session_id IN ($id_checked)");
1751
        Database::query("DELETE FROM $tbl_url_session WHERE session_id IN($id_checked)");
1752
1753
        Database::query("DELETE FROM $trackCourseAccess WHERE session_id IN($id_checked)");
1754
        Database::query("DELETE FROM $trackAccess WHERE access_session_id IN($id_checked)");
1755
1756
        $sql = "UPDATE $ticket SET session_id = NULL WHERE session_id IN ($id_checked)";
1757
        Database::query($sql);
1758
1759
        $sql = "DELETE FROM $tbl_session WHERE id IN ($id_checked)";
1760
        Database::query($sql);
1761
1762
        $extraFieldValue = new ExtraFieldValue('session');
1763
        $extraFieldValue->deleteValuesByItem($id_checked);
1764
1765
        $repo->deleteResource(
1766
            $id_checked,
1767
            SequenceResource::SESSION_TYPE
1768
        );
1769
1770
        // Add event to system log
1771
        Event::addEvent(
1772
            LOG_SESSION_DELETE,
1773
            LOG_SESSION_ID,
1774
            $id_checked,
1775
            api_get_utc_datetime(),
1776
            $userId
1777
        );
1778
1779
        return true;
1780
    }
1781
1782
    /**
1783
     * @param int $id promotion id
1784
     *
1785
     * @return bool
1786
     */
1787
    public static function clear_session_ref_promotion($id)
1788
    {
1789
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1790
        $id = intval($id);
1791
        $sql = "UPDATE $tbl_session 
1792
                SET promotion_id = 0
1793
                WHERE promotion_id = $id";
1794
        if (Database::query($sql)) {
1795
            return true;
1796
        } else {
1797
            return false;
1798
        }
1799
    }
1800
1801
    /**
1802
     * Subscribes students to the given session and optionally (default)
1803
     * unsubscribes previous users
1804
     *
1805
     * @author Carlos Vargas from existing code
1806
     * @author Julio Montoya. Cleaning code.
1807
     * @param int $id_session
1808
     * @param array $user_list
1809
     * @param int $session_visibility
1810
     * @param bool $empty_users
1811
     * @return bool
1812
     */
1813
    public static function subscribe_users_to_session(
1814
        $id_session,
1815
        $user_list,
1816
        $session_visibility = SESSION_VISIBLE_READ_ONLY,
1817
        $empty_users = true
1818
    ) {
1819
        if ($id_session != strval(intval($id_session))) {
1820
            return false;
1821
        }
1822
1823
        foreach ($user_list as $intUser) {
1824
            if ($intUser != strval(intval($intUser))) {
1825
                return false;
1826
            }
1827
        }
1828
1829
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1830
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1831
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1832
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1833
1834
        $entityManager = Database::getManager();
1835
        $session = $entityManager->find('ChamiloCoreBundle:Session', $id_session);
1836
1837
        // from function parameter
1838
        if (empty($session_visibility)) {
1839
            $session_visibility = $session->getVisibility();
1840
            //default status loaded if empty
1841
            // by default readonly 1
1842
            if (empty($session_visibility)) {
1843
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
1844
            }
1845
        } else {
1846
            if (!in_array($session_visibility, [SESSION_VISIBLE_READ_ONLY, SESSION_VISIBLE, SESSION_INVISIBLE])) {
1847
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
1848
            }
1849
        }
1850
1851
        $sql = "SELECT user_id FROM $tbl_session_rel_course_rel_user
1852
                WHERE session_id = $id_session AND status = 0";
1853
        $result = Database::query($sql);
1854
        $existingUsers = [];
1855
        while ($row = Database::fetch_array($result)) {
1856
            $existingUsers[] = $row['user_id'];
1857
        }
1858
1859
        $sql = "SELECT c_id FROM $tbl_session_rel_course
1860
                WHERE session_id = $id_session";
1861
        $result = Database::query($sql);
1862
        $course_list = [];
1863
        while ($row = Database::fetch_array($result)) {
1864
            $course_list[] = $row['c_id'];
1865
        }
1866
1867
        if ($session->getSendSubscriptionNotification() &&
1868
            is_array($user_list)
1869
        ) {
1870
            // Sending emails only
1871
            foreach ($user_list as $user_id) {
1872
                if (in_array($user_id, $existingUsers)) {
1873
                    continue;
1874
                }
1875
1876
                $tplSubject = new Template(
1877
                    null,
1878
                    false,
1879
                    false,
1880
                    false,
1881
                    false,
1882
                    false
1883
                );
1884
                $layoutSubject = $tplSubject->get_template(
1885
                    'mail/subject_subscription_to_session_confirmation.tpl'
1886
                );
1887
                $subject = $tplSubject->fetch($layoutSubject);
1888
                $user_info = api_get_user_info($user_id);
1889
1890
                $tplContent = new Template(
1891
                    null,
1892
                    false,
1893
                    false,
1894
                    false,
1895
                    false,
1896
                    false
1897
                );
1898
                // Variables for default template
1899
                $tplContent->assign(
1900
                    'complete_name',
1901
                    stripslashes($user_info['complete_name'])
1902
                );
1903
                $tplContent->assign('session_name', $session->getName());
1904
                $tplContent->assign(
1905
                    'session_coach',
1906
                    $session->getGeneralCoach()->getCompleteName()
1907
                );
1908
                $layoutContent = $tplContent->get_template(
1909
                    'mail/content_subscription_to_session_confirmation.tpl'
1910
                );
1911
                $content = $tplContent->fetch($layoutContent);
1912
1913
                api_mail_html(
1914
                    $user_info['complete_name'],
1915
                    $user_info['mail'],
1916
                    $subject,
1917
                    $content,
1918
                    api_get_person_name(
1919
                        api_get_setting('administratorName'),
1920
                        api_get_setting('administratorSurname')
1921
                    ),
1922
                    api_get_setting('emailAdministrator')
1923
                );
1924
            }
1925
        }
1926
1927
        foreach ($course_list as $courseId) {
1928
            // for each course in the session
1929
            $nbr_users = 0;
1930
            $courseId = intval($courseId);
1931
1932
            $sql = "SELECT DISTINCT user_id
1933
                    FROM $tbl_session_rel_course_rel_user
1934
                    WHERE
1935
                        session_id = $id_session AND
1936
                        c_id = $courseId AND
1937
                        status = 0
1938
                    ";
1939
            $result = Database::query($sql);
1940
            $existingUsers = [];
1941
            while ($row = Database::fetch_array($result)) {
1942
                $existingUsers[] = $row['user_id'];
1943
            }
1944
1945
            // Delete existing users
1946
            if ($empty_users) {
1947
                foreach ($existingUsers as $existing_user) {
1948
                    if (!in_array($existing_user, $user_list)) {
1949
                        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
1950
                                WHERE
1951
                                    session_id = $id_session AND
1952
                                    c_id = $courseId AND
1953
                                    user_id = $existing_user AND
1954
                                    status = 0 ";
1955
                        $result = Database::query($sql);
1956
1957
                        Event::addEvent(
1958
                            LOG_SESSION_DELETE_USER_COURSE,
1959
                            LOG_USER_ID,
1960
                            $existing_user,
1961
                            api_get_utc_datetime(),
1962
                            api_get_user_id(),
1963
                            $courseId,
1964
                            $id_session
1965
                        );
1966
1967
                        if (Database::affected_rows($result)) {
1968
                            $nbr_users--;
1969
                        }
1970
                    }
1971
                }
1972
            }
1973
1974
            // Replace with this new function
1975
            // insert new users into session_rel_course_rel_user and ignore if they already exist
1976
            foreach ($user_list as $enreg_user) {
1977
                if (!in_array($enreg_user, $existingUsers)) {
1978
                    $status = self::get_user_status_in_course_session(
1979
                        $enreg_user,
1980
                        $courseId,
1981
                        $id_session
1982
                    );
1983
                    // Avoid duplicate entries.
1984
                    if ($status === false || ($status !== false && $status != 0)) {
1985
                        $enreg_user = (int) $enreg_user;
1986
                        $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id, visibility, status)
1987
                                VALUES($id_session, $courseId, $enreg_user, $session_visibility, 0)";
1988
                        $result = Database::query($sql);
1989
                        if (Database::affected_rows($result)) {
1990
                            $nbr_users++;
1991
                        }
1992
1993
                        Event::addEvent(
1994
                            LOG_SESSION_ADD_USER_COURSE,
1995
                            LOG_USER_ID,
1996
                            $enreg_user,
1997
                            api_get_utc_datetime(),
1998
                            api_get_user_id(),
1999
                            $courseId,
2000
                            $id_session
2001
                        );
2002
                    }
2003
                }
2004
            }
2005
2006
            // Count users in this session-course relation
2007
            $sql = "SELECT COUNT(user_id) as nbUsers
2008
                    FROM $tbl_session_rel_course_rel_user
2009
                    WHERE session_id = $id_session AND c_id = $courseId AND status<>2";
2010
            $rs = Database::query($sql);
2011
            list($nbr_users) = Database::fetch_array($rs);
2012
            // update the session-course relation to add the users total
2013
            $sql = "UPDATE $tbl_session_rel_course SET nbr_users = $nbr_users
2014
                    WHERE session_id = $id_session AND c_id = $courseId";
2015
            Database::query($sql);
2016
        }
2017
2018
        // Delete users from the session
2019
        if ($empty_users === true) {
2020
            $sql = "DELETE FROM $tbl_session_rel_user
2021
                    WHERE session_id = $id_session AND relation_type<>".SESSION_RELATION_TYPE_RRHH."";
2022
            Database::query($sql);
2023
        }
2024
2025
        // Insert missing users into session
2026
        $nbr_users = 0;
2027
        foreach ($user_list as $enreg_user) {
2028
            $isUserSubscribed = self::isUserSubscribedAsStudent($id_session, $enreg_user);
2029
            if ($isUserSubscribed === false) {
2030
                $enreg_user = (int)$enreg_user;
2031
                $nbr_users++;
2032
                $sql = "INSERT IGNORE INTO $tbl_session_rel_user (relation_type, session_id, user_id, registered_at)
2033
                        VALUES (0, $id_session, $enreg_user, '".api_get_utc_datetime()."')";
2034
                Database::query($sql);
2035
            }
2036
        }
2037
2038
        // update number of users in the session
2039
        $nbr_users = count($user_list);
2040
        if ($empty_users) {
2041
            // update number of users in the session
2042
            $sql = "UPDATE $tbl_session SET nbr_users= $nbr_users
2043
                    WHERE id = $id_session ";
2044
            Database::query($sql);
2045
        } else {
2046
            $sql = "UPDATE $tbl_session SET nbr_users = nbr_users + $nbr_users
2047
                    WHERE id = $id_session";
2048
            Database::query($sql);
2049
        }
2050
    }
2051
2052
    /**
2053
     * Returns user list of the current users subscribed in the course-session
2054
     * @param int $sessionId
2055
     * @param array $courseInfo
2056
     * @param int $status
2057
     *
2058
     * @return array
2059
     */
2060
    public static function getUsersByCourseSession(
2061
        $sessionId,
2062
        $courseInfo,
2063
        $status = null
2064
    ) {
2065
        $sessionId = intval($sessionId);
2066
        $courseId = $courseInfo['real_id'];
2067
2068
        if (empty($sessionId) || empty($courseId)) {
2069
            return [];
2070
        }
2071
2072
        $statusCondition = null;
2073
        if (isset($status) && !is_null($status)) {
2074
            $status = intval($status);
2075
            $statusCondition = " AND status = $status";
2076
        }
2077
2078
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2079
2080
        $sql = "SELECT DISTINCT user_id
2081
                FROM $table
2082
                WHERE
2083
                    session_id = $sessionId AND
2084
                    c_id = $courseId
2085
                    $statusCondition
2086
                ";
2087
2088
        $result = Database::query($sql);
2089
        $existingUsers = [];
2090
        while ($row = Database::fetch_array($result)) {
2091
            $existingUsers[] = $row['user_id'];
2092
        }
2093
2094
        return $existingUsers;
2095
    }
2096
2097
    /**
2098
    * Returns user list of the current users subscribed in the course-session
2099
    * @param array $sessionList
2100
    * @param array $courseList
2101
    * @param int $status
2102
    * @param int $start
2103
    * @param int $limit
2104
    *
2105
    * @return array
2106
    */
2107
    public static function getUsersByCourseAndSessionList(
2108
        $sessionList,
2109
        $courseList,
2110
        $status = null,
2111
        $start = null,
2112
        $limit = null
2113
    ) {
2114
        if (empty($sessionList) || empty($courseList)) {
2115
            return [];
2116
        }
2117
        $sessionListToString = implode("','", $sessionList);
2118
        $courseListToString = implode("','", $courseList);
2119
2120
        $statusCondition = null;
2121
        if (isset($status) && !is_null($status)) {
2122
            $status = intval($status);
2123
            $statusCondition = " AND status = $status";
2124
        }
2125
2126
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2127
2128
        $sql = "SELECT DISTINCT user_id
2129
                FROM $table
2130
                WHERE
2131
                    session_id IN ('$sessionListToString') AND
2132
                    c_id IN ('$courseListToString')
2133
                    $statusCondition
2134
                ";
2135
        if (!is_null($start) && !is_null($limit)) {
2136
            $start = (int) $start;
2137
            $limit = (int) $limit;
2138
            $sql .= "LIMIT $start, $limit";
2139
        }
2140
        $result = Database::query($sql);
2141
        $existingUsers = [];
2142
        while ($row = Database::fetch_array($result)) {
2143
            $existingUsers[] = $row['user_id'];
2144
        }
2145
2146
        return $existingUsers;
2147
    }
2148
2149
    /**
2150
     * Remove a list of users from a course-session
2151
     * @param array $userList
2152
     * @param int $sessionId
2153
     * @param array $courseInfo
2154
     * @param int $status
2155
     * @param bool $updateTotal
2156
     * @return bool
2157
     */
2158
    public static function removeUsersFromCourseSession(
2159
        $userList,
2160
        $sessionId,
2161
        $courseInfo,
2162
        $status = null,
2163
        $updateTotal = true
2164
    ) {
2165
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2166
        $tableSessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2167
        $sessionId = intval($sessionId);
2168
2169
        if (empty($sessionId) || empty($userList) || empty($courseInfo)) {
2170
            return false;
2171
        }
2172
2173
        is_array($courseInfo) ? $courseId = $courseInfo['real_id'] : $courseId = $courseInfo;
2174
2175
        $statusCondition = null;
2176
        if (isset($status) && !is_null($status)) {
2177
            $status = intval($status);
2178
            $statusCondition = " AND status = $status";
2179
        }
2180
2181
        foreach ($userList as $userId) {
2182
            $userId = intval($userId);
2183
            $sql = "DELETE FROM $table
2184
                    WHERE
2185
                        session_id = $sessionId AND
2186
                        c_id = $courseId AND
2187
                        user_id = $userId
2188
                        $statusCondition
2189
                    ";
2190
            Database::query($sql);
2191
        }
2192
2193
        if ($updateTotal) {
2194
            // Count users in this session-course relation
2195
            $sql = "SELECT COUNT(user_id) as nbUsers
2196
                    FROM $table
2197
                    WHERE
2198
                        session_id = $sessionId AND
2199
                        c_id = $courseId AND
2200
                        status <> 2";
2201
            $result = Database::query($sql);
2202
            list($userCount) = Database::fetch_array($result);
2203
2204
            // update the session-course relation to add the users total
2205
            $sql = "UPDATE $tableSessionCourse
2206
                    SET nbr_users = $userCount
2207
                    WHERE
2208
                        session_id = $sessionId AND
2209
                        c_id = $courseId";
2210
            Database::query($sql);
2211
        }
2212
    }
2213
2214
    /**
2215
     * Subscribe a user to an specific course inside a session.
2216
     *
2217
     * @param array $user_list
2218
     * @param int $session_id
2219
     * @param string $course_code
2220
     * @param int $session_visibility
2221
     * @param bool $removeUsersNotInList
2222
     * @return bool
2223
     */
2224
    public static function subscribe_users_to_session_course(
2225
        $user_list,
2226
        $session_id,
2227
        $course_code,
2228
        $session_visibility = SESSION_VISIBLE_READ_ONLY,
2229
        $removeUsersNotInList = false
2230
    ) {
2231
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2232
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2233
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2234
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2235
2236
        if (empty($session_id) || empty($course_code)) {
2237
            return false;
2238
        }
2239
2240
        $session_id = intval($session_id);
2241
        $course_code = Database::escape_string($course_code);
2242
        $courseInfo = api_get_course_info($course_code);
2243
        $courseId = $courseInfo['real_id'];
2244
        $session_visibility = intval($session_visibility);
2245
2246
        if ($removeUsersNotInList) {
2247
            $currentUsers = self::getUsersByCourseSession($session_id, $courseInfo, 0);
2248
2249
            if (!empty($user_list)) {
2250
                $userToDelete = array_diff($currentUsers, $user_list);
2251
            } else {
2252
                $userToDelete = $currentUsers;
2253
            }
2254
2255
            if (!empty($userToDelete)) {
2256
                self::removeUsersFromCourseSession(
2257
                    $userToDelete,
2258
                    $session_id,
2259
                    $courseInfo,
2260
                    0,
2261
                    true
2262
                );
2263
            }
2264
        }
2265
2266
        $nbr_users = 0;
2267
        foreach ($user_list as $enreg_user) {
2268
            $enreg_user = intval($enreg_user);
2269
            // Checking if user exists in session - course - user table.
2270
            $sql = "SELECT count(user_id) as count
2271
                    FROM $tbl_session_rel_course_rel_user
2272
                    WHERE
2273
                        session_id = $session_id AND
2274
                        c_id = $courseId and
2275
                        user_id = $enreg_user ";
2276
            $result = Database::query($sql);
2277
            $count = 0;
2278
2279
            if (Database::num_rows($result) > 0) {
2280
                $row = Database::fetch_array($result, 'ASSOC');
2281
                $count = $row['count'];
2282
            }
2283
2284
            if ($count == 0) {
2285
                $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id, visibility)
2286
                        VALUES ($session_id, $courseId, $enreg_user, $session_visibility)";
2287
                $result = Database::query($sql);
2288
                if (Database::affected_rows($result)) {
2289
                    $nbr_users++;
2290
                }
2291
            }
2292
2293
            // Checking if user exists in session - user table.
2294
            $sql = "SELECT count(user_id) as count
2295
                    FROM $tbl_session_rel_user
2296
                    WHERE session_id = $session_id AND user_id = $enreg_user ";
2297
            $result = Database::query($sql);
2298
            $count = 0;
2299
2300
            if (Database::num_rows($result) > 0) {
2301
                $row = Database::fetch_array($result, 'ASSOC');
2302
                $count = $row['count'];
2303
            }
2304
2305
            if (empty($count)) {
2306
                // If user is not registered to a session then add it.
2307
                $sql = "INSERT IGNORE INTO $tbl_session_rel_user (session_id, user_id, registered_at)
2308
                        VALUES ($session_id, $enreg_user, '".api_get_utc_datetime()."')";
2309
                Database::query($sql);
2310
2311
                $sql = "UPDATE $tbl_session SET nbr_users = nbr_users + 1
2312
                        WHERE id = $session_id ";
2313
                Database::query($sql);
2314
            }
2315
        }
2316
2317
        // count users in this session-course relation
2318
        $sql = "SELECT COUNT(user_id) as nbUsers
2319
                FROM $tbl_session_rel_course_rel_user
2320
                WHERE session_id = $session_id AND c_id = $courseId AND status <> 2";
2321
        $rs = Database::query($sql);
2322
        list($nbr_users) = Database::fetch_array($rs);
2323
        // update the session-course relation to add the users total
2324
        $sql = "UPDATE $tbl_session_rel_course
2325
                SET nbr_users = $nbr_users
2326
                WHERE session_id = $session_id AND c_id = $courseId";
2327
        Database::query($sql);
2328
    }
2329
2330
    /**
2331
     * Unsubscribe user from session
2332
     *
2333
     * @param int Session id
2334
     * @param int User id
2335
     * @return bool True in case of success, false in case of error
2336
     */
2337
    public static function unsubscribe_user_from_session($session_id, $user_id)
2338
    {
2339
        $session_id = (int) $session_id;
2340
        $user_id = (int) $user_id;
2341
2342
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2343
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2344
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2345
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2346
2347
        $sql = "DELETE FROM $tbl_session_rel_user
2348
                WHERE
2349
                    session_id = $session_id AND
2350
                    user_id = $user_id AND
2351
                    relation_type <> ".SESSION_RELATION_TYPE_RRHH."";
2352
        $result = Database::query($sql);
2353
        $return = Database::affected_rows($result);
2354
2355
        // Update number of users
2356
        $sql = "UPDATE $tbl_session
2357
                SET nbr_users = nbr_users - $return
2358
                WHERE id = $session_id ";
2359
        Database::query($sql);
2360
2361
        // Get the list of courses related to this session
2362
        $course_list = self::get_course_list_by_session_id($session_id);
2363
        if (!empty($course_list)) {
2364
            foreach ($course_list as $course) {
2365
                $courseId = $course['id'];
2366
                // Delete user from course
2367
                $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2368
                        WHERE session_id = $session_id AND c_id = $courseId AND user_id = $user_id";
2369
                $result = Database::query($sql);
2370
2371
                Event::addEvent(
2372
                    LOG_SESSION_DELETE_USER_COURSE,
2373
                    LOG_USER_ID,
2374
                    $user_id,
2375
                    api_get_utc_datetime(),
2376
                    api_get_user_id(),
2377
                    $courseId,
2378
                    $session_id
2379
                );
2380
2381
                if (Database::affected_rows($result)) {
2382
                    // Update number of users in this relation
2383
                    $sql = "UPDATE $tbl_session_rel_course SET 
2384
                            nbr_users = nbr_users - 1
2385
                            WHERE session_id = $session_id AND c_id = $courseId";
2386
                    Database::query($sql);
2387
                }
2388
            }
2389
        }
2390
2391
        return true;
2392
    }
2393
2394
    /**
2395
     * Subscribes courses to the given session and optionally (default)
2396
     * unsubscribe previous users
2397
     * @author Carlos Vargas from existing code
2398
     * @param   int $sessionId
2399
     * @param   array $courseList List of courses int ids
2400
     * @param   bool $removeExistingCoursesWithUsers Whether to unsubscribe
2401
     * existing courses and users (true, default) or not (false)
2402
     * @param bool $copyEvaluation from base course to session course
2403
     * @return    void    Nothing, or false on error
2404
     * */
2405
    public static function add_courses_to_session(
2406
        $sessionId,
2407
        $courseList,
2408
        $removeExistingCoursesWithUsers = true,
2409
        $copyEvaluation = false
2410
    ) {
2411
        $sessionId = intval($sessionId);
2412
2413
        if (empty($sessionId) || empty($courseList)) {
2414
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type void.
Loading history...
2415
        }
2416
2417
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2418
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2419
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2420
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2421
2422
        // Get list of courses subscribed to this session
2423
        $sql = "SELECT c_id
2424
                FROM $tbl_session_rel_course
2425
                WHERE session_id = $sessionId";
2426
        $rs = Database::query($sql);
2427
        $existingCourses = Database::store_result($rs);
2428
        $nbr_courses = count($existingCourses);
2429
2430
        // Get list of users subscribed to this session
2431
        $sql = "SELECT user_id
2432
                FROM $tbl_session_rel_user
2433
                WHERE
2434
                    session_id = $sessionId AND
2435
                    relation_type<>".SESSION_RELATION_TYPE_RRHH;
2436
        $result = Database::query($sql);
2437
        $user_list = Database::store_result($result);
2438
2439
        // Remove existing courses from the session.
2440
        if ($removeExistingCoursesWithUsers === true && !empty($existingCourses)) {
2441
            foreach ($existingCourses as $existingCourse) {
2442
                if (!in_array($existingCourse['c_id'], $courseList)) {
2443
                    $sql = "DELETE FROM $tbl_session_rel_course
2444
                            WHERE
2445
                                c_id = ".$existingCourse['c_id']." AND
2446
                                session_id = $sessionId";
2447
                    Database::query($sql);
2448
2449
                    $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2450
                            WHERE
2451
                                c_id = ".$existingCourse['c_id']." AND
2452
                                session_id = $sessionId";
2453
                    Database::query($sql);
2454
2455
                    Event::addEvent(
2456
                        LOG_SESSION_DELETE_COURSE,
2457
                        LOG_COURSE_ID,
2458
                        $existingCourse['c_id'],
2459
                        api_get_utc_datetime(),
2460
                        api_get_user_id(),
2461
                        $existingCourse['c_id'],
2462
                        $sessionId
2463
                    );
2464
2465
                    CourseManager::remove_course_ranking(
2466
                        $existingCourse['c_id'],
2467
                        $sessionId
2468
                    );
2469
                    $nbr_courses--;
2470
                }
2471
            }
2472
        }
2473
2474
        // Pass through the courses list we want to add to the session
2475
        foreach ($courseList as $courseId) {
2476
            $courseInfo = api_get_course_info_by_id($courseId);
2477
2478
            // If course doesn't exists continue!
2479
            if (empty($courseInfo)) {
2480
                continue;
2481
            }
2482
2483
            $exists = false;
2484
            // check if the course we want to add is already subscribed
2485
            foreach ($existingCourses as $existingCourse) {
2486
                if ($courseId == $existingCourse['c_id']) {
2487
                    $exists = true;
2488
                }
2489
            }
2490
2491
            if (!$exists) {
2492
                // Copy gradebook categories and links (from base course)
2493
                // to the new course session
2494
                if ($copyEvaluation) {
2495
                    $cats = Category::load(null, null, $courseInfo['code']);
2496
                    if (!empty($cats)) {
2497
                        $sessionCategory = Category:: load(
2498
                            null,
2499
                            null,
2500
                            $courseInfo['code'],
2501
                            null,
2502
                            null,
2503
                            $sessionId,
2504
                            false
2505
                        );
2506
2507
                        // @todo remove commented code
2508
                        if (empty($sessionCategory)) {
2509
                            // There is no category for this course+session, so create one
2510
                            $cat = new Category();
2511
                            $sessionName = api_get_session_name($sessionId);
2512
                            $cat->set_name($courseInfo['code'].' - '.get_lang('Session').' '.$sessionName);
2513
                            $cat->set_session_id($sessionId);
2514
                            $cat->set_course_code($courseInfo['code']);
2515
                            $cat->set_description(null);
2516
                            //$cat->set_user_id($stud_id);
2517
                            $cat->set_parent_id(0);
2518
                            $cat->set_weight(100);
2519
                            $cat->set_visible(0);
2520
                            $cat->set_certificate_min_score(75);
2521
                            $cat->add();
2522
                            $sessionGradeBookCategoryId = $cat->get_id();
2523
                        } else {
2524
                            if (!empty($sessionCategory[0])) {
2525
                                $sessionGradeBookCategoryId = $sessionCategory[0]->get_id();
2526
                            }
2527
                        }
2528
2529
                        $categoryIdList = [];
2530
                        /** @var Category $cat */
2531
                        foreach ($cats as $cat) {
2532
                            $categoryIdList[$cat->get_id()] = $cat->get_id();
2533
                        }
2534
2535
                        $newCategoryIdList = [];
2536
                        foreach ($cats as $cat) {
2537
                            $links = $cat->get_links(
2538
                                null,
2539
                                false,
2540
                                $courseInfo['code'],
2541
                                0
2542
                            );
2543
2544
                            //$cat->set_session_id($sessionId);
2545
                            //$oldCategoryId = $cat->get_id();
2546
                            //$newId = $cat->add();
2547
                            //$newCategoryIdList[$oldCategoryId] = $newId;
2548
                            //$parentId = $cat->get_parent_id();
2549
2550
                            /*if (!empty($parentId)) {
2551
                                $newParentId = $newCategoryIdList[$parentId];
2552
                                $cat->set_parent_id($newParentId);
2553
                                $cat->save();
2554
                            }*/
2555
2556
                            if (!empty($links)) {
2557
                                /** @var AbstractLink $link */
2558
                                foreach ($links as $link) {
2559
                                    //$newCategoryId = $newCategoryIdList[$link->get_category_id()];
2560
                                    $link->set_category_id(
2561
                                        $sessionGradeBookCategoryId
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $sessionGradeBookCategoryId does not seem to be defined for all execution paths leading up to this point.
Loading history...
2562
                                    );
2563
                                    $link->add();
2564
                                }
2565
                            }
2566
2567
                            $evaluationList = $cat->get_evaluations(
2568
                                null,
2569
                                false,
2570
                                $courseInfo['code'],
2571
                                0
2572
                            );
2573
2574
                            if (!empty($evaluationList)) {
2575
                                /** @var Evaluation $evaluation */
2576
                                foreach ($evaluationList as $evaluation) {
2577
                                    //$evaluationId = $newCategoryIdList[$evaluation->get_category_id()];
2578
                                    $evaluation->set_category_id(
2579
                                        $sessionGradeBookCategoryId
2580
                                    );
2581
                                    $evaluation->add();
2582
                                }
2583
                            }
2584
                        }
2585
2586
                        // Create
2587
                        DocumentManager::generateDefaultCertificate(
2588
                            $courseInfo,
2589
                            true,
2590
                            $sessionId
2591
                        );
2592
                    }
2593
                }
2594
2595
                // If the course isn't subscribed yet
2596
                $sql = "INSERT INTO $tbl_session_rel_course (session_id, c_id, nbr_users, position)
2597
                        VALUES ($sessionId, $courseId, 0, 0)";
2598
                Database::query($sql);
2599
2600
                Event::addEvent(
2601
                    LOG_SESSION_ADD_COURSE,
2602
                    LOG_COURSE_ID,
2603
                    $courseId,
2604
                    api_get_utc_datetime(),
2605
                    api_get_user_id(),
2606
                    $courseId,
2607
                    $sessionId
2608
                );
2609
2610
                // We add the current course in the existing courses array,
2611
                // to avoid adding another time the current course
2612
                $existingCourses[] = ['c_id' => $courseId];
2613
                $nbr_courses++;
2614
2615
                // subscribe all the users from the session to this course inside the session
2616
                $nbr_users = 0;
2617
                foreach ($user_list as $enreg_user) {
2618
                    $enreg_user_id = intval($enreg_user['user_id']);
2619
                    $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id)
2620
                            VALUES ($sessionId, $courseId, $enreg_user_id)";
2621
                    $result = Database::query($sql);
2622
2623
                    Event::addEvent(
2624
                        LOG_SESSION_ADD_USER_COURSE,
2625
                        LOG_USER_ID,
2626
                        $enreg_user_id,
2627
                        api_get_utc_datetime(),
2628
                        api_get_user_id(),
2629
                        $courseId,
2630
                        $sessionId
2631
                    );
2632
2633
                    if (Database::affected_rows($result)) {
2634
                        $nbr_users++;
2635
                    }
2636
                }
2637
                $sql = "UPDATE $tbl_session_rel_course
2638
                        SET nbr_users = $nbr_users
2639
                        WHERE session_id = $sessionId AND c_id = $courseId";
2640
                Database::query($sql);
2641
            }
2642
        }
2643
2644
        $sql = "UPDATE $tbl_session
2645
                SET nbr_courses = $nbr_courses
2646
                WHERE id = $sessionId";
2647
        Database::query($sql);
2648
    }
2649
2650
    /**
2651
     * Unsubscribe course from a session
2652
     *
2653
     * @param int $session_id
2654
     * @param int $course_id
2655
     * @return bool True in case of success, false otherwise
2656
     */
2657
    public static function unsubscribe_course_from_session($session_id, $course_id)
2658
    {
2659
        $session_id = (int) $session_id;
2660
        $course_id = (int) $course_id;
2661
2662
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2663
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2664
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2665
2666
        // Get course code
2667
        $course_code = CourseManager::get_course_code_from_course_id($course_id);
2668
        $course_id = intval($course_id);
2669
2670
        if (empty($course_code)) {
2671
            return false;
2672
        }
2673
2674
        // Unsubscribe course
2675
        $sql = "DELETE FROM $tbl_session_rel_course
2676
                WHERE c_id = $course_id AND session_id = $session_id";
2677
        $result = Database::query($sql);
2678
        $nb_affected = Database::affected_rows($result);
2679
2680
        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2681
                WHERE c_id = $course_id AND session_id = $session_id";
2682
        Database::query($sql);
2683
2684
        Event::addEvent(
2685
            LOG_SESSION_DELETE_COURSE,
2686
            LOG_COURSE_ID,
2687
            $course_id,
2688
            api_get_utc_datetime(),
2689
            api_get_user_id(),
2690
            $course_id,
2691
            $session_id
2692
        );
2693
2694
        if ($nb_affected > 0) {
2695
            // Update number of courses in the session
2696
            $sql = "UPDATE $tbl_session SET nbr_courses= nbr_courses - $nb_affected
2697
                    WHERE id = $session_id";
2698
            Database::query($sql);
2699
            return true;
2700
        } else {
2701
            return false;
2702
        }
2703
    }
2704
2705
    /**
2706
     * Creates a new extra field for a given session
2707
     * @param string $variable Field's internal variable name
2708
     * @param int $fieldType Field's type
2709
     * @param string $displayText Field's language var name
2710
     * @param string $default Field's default value
2711
     * @return int     new extra field id
2712
     */
2713
    public static function create_session_extra_field(
2714
        $variable,
2715
        $fieldType,
2716
        $displayText,
2717
        $default = ''
2718
    ) {
2719
        $extraField = new ExtraFieldModel('session');
2720
        $params = [
2721
            'variable' => $variable,
2722
            'field_type' => $fieldType,
2723
            'display_text' => $displayText,
2724
            'default_value' => $default
2725
        ];
2726
2727
        return $extraField->save($params);
2728
    }
2729
2730
    /**
2731
     * Update an extra field value for a given session
2732
     * @param integer    Course ID
2733
     * @param string    Field variable name
2734
     * @param string    Field value
2735
     * @return boolean    true if field updated, false otherwise
2736
     */
2737
    public static function update_session_extra_field_value($sessionId, $variable, $value = '')
2738
    {
2739
        $extraFieldValue = new ExtraFieldValue('session');
2740
        $params = [
2741
            'item_id' => $sessionId,
2742
            'variable' => $variable,
2743
            'value' => $value,
2744
        ];
2745
        return $extraFieldValue->save($params);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $extraFieldValue->save($params) also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
2746
    }
2747
2748
    /**
2749
     * Checks the relationship between a session and a course.
2750
     * @param int $session_id
2751
     * @param int $courseId
2752
     * @return bool Returns TRUE if the session and the course are related, FALSE otherwise.
2753
     * */
2754
    public static function relation_session_course_exist($session_id, $courseId)
2755
    {
2756
        $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2757
        $return_value = false;
2758
        $sql = "SELECT c_id FROM $tbl_session_course
2759
                WHERE
2760
                  session_id = ".intval($session_id)." AND
2761
                  c_id = " . intval($courseId);
2762
        $result = Database::query($sql);
2763
        $num = Database::num_rows($result);
2764
        if ($num > 0) {
2765
            $return_value = true;
2766
        }
2767
        return $return_value;
2768
    }
2769
2770
    /**
2771
     * Get the session information by name
2772
     * @param string $name
2773
     * @return mixed false if the session does not exist, array if the session exist
2774
     * */
2775
    public static function get_session_by_name($name)
2776
    {
2777
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2778
        $name = Database::escape_string(trim($name));
2779
        if (empty($name)) {
2780
            return false;
2781
        }
2782
2783
        $sql = 'SELECT *
2784
		        FROM '.$tbl_session.'
2785
		        WHERE name = "'.$name.'"';
2786
        $result = Database::query($sql);
2787
        $num = Database::num_rows($result);
2788
        if ($num > 0) {
2789
            return Database::fetch_array($result);
2790
        } else {
2791
            return false;
2792
        }
2793
    }
2794
2795
    /**
2796
     * Create a session category
2797
     * @author Jhon Hinojosa <[email protected]>, from existing code
2798
     * @param string        name
2799
     * @param integer        year_start
2800
     * @param integer        month_start
2801
     * @param integer        day_start
2802
     * @param integer        year_end
2803
     * @param integer        month_end
2804
     * @param integer        day_end
2805
     * @return int session ID
2806
     * */
2807
    public static function create_category_session(
2808
        $sname,
2809
        $syear_start,
2810
        $smonth_start,
2811
        $sday_start,
2812
        $syear_end,
2813
        $smonth_end,
2814
        $sday_end
2815
    ) {
2816
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2817
        $name = trim($sname);
2818
        $year_start = intval($syear_start);
2819
        $month_start = intval($smonth_start);
2820
        $day_start = intval($sday_start);
2821
        $year_end = intval($syear_end);
2822
        $month_end = intval($smonth_end);
2823
        $day_end = intval($sday_end);
2824
2825
        $date_start = "$year_start-".(($month_start < 10) ? "0$month_start" : $month_start)."-".(($day_start < 10) ? "0$day_start" : $day_start);
2826
        $date_end = "$year_end-".(($month_end < 10) ? "0$month_end" : $month_end)."-".(($day_end < 10) ? "0$day_end" : $day_end);
2827
2828
        if (empty($name)) {
2829
            $msg = get_lang('SessionCategoryNameIsRequired');
2830
            return $msg;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $msg returns the type string which is incompatible with the documented return type integer.
Loading history...
2831
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
2832
            $msg = get_lang('InvalidStartDate');
2833
            return $msg;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $msg returns the type string which is incompatible with the documented return type integer.
Loading history...
2834
        } elseif (!$month_end && !$day_end && !$year_end) {
2835
            $date_end = '';
2836
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
2837
            $msg = get_lang('InvalidEndDate');
2838
            return $msg;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $msg returns the type string which is incompatible with the documented return type integer.
Loading history...
2839
        } elseif ($date_start >= $date_end) {
2840
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
2841
            return $msg;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $msg returns the type string which is incompatible with the documented return type integer.
Loading history...
2842
        }
2843
2844
        $access_url_id = api_get_current_access_url_id();
2845
        $params = [
2846
            'name' => $name,
2847
            'date_start' => $date_start,
2848
            'access_url_id' => $access_url_id,
2849
        ];
2850
2851
        if (!empty($date_end)) {
2852
            $params['date_end'] = $date_end;
2853
        }
2854
2855
        $id = Database::insert($tbl_session_category, $params);
2856
2857
        // Add event to system log
2858
        $user_id = api_get_user_id();
2859
        Event::addEvent(
2860
            LOG_SESSION_CATEGORY_CREATE,
2861
            LOG_SESSION_CATEGORY_ID,
2862
            $id,
0 ignored issues
show
Bug introduced by
It seems like $id can also be of type false; however, parameter $event_value of Event::addEvent() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2862
            /** @scrutinizer ignore-type */ $id,
Loading history...
2863
            api_get_utc_datetime(),
2864
            $user_id
2865
        );
2866
2867
        return $id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $id could also return false which is incompatible with the documented return type integer. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
2868
    }
2869
2870
    /**
2871
     * Edit a sessions category
2872
     * @author Jhon Hinojosa <[email protected]>,from existing code
2873
     * @param integer        id
2874
     * @param string        name
2875
     * @param integer        year_start
2876
     * @param integer        month_start
2877
     * @param integer        day_start
2878
     * @param integer        year_end
2879
     * @param integer        month_end
2880
     * @param integer        day_end
2881
     * @return bool
2882
     * The parameter id is a primary key
2883
     * */
2884
    public static function edit_category_session(
2885
        $id,
2886
        $sname,
2887
        $syear_start,
2888
        $smonth_start,
2889
        $sday_start,
2890
        $syear_end,
2891
        $smonth_end,
2892
        $sday_end
2893
    ) {
2894
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2895
        $name = trim($sname);
2896
        $year_start = intval($syear_start);
2897
        $month_start = intval($smonth_start);
2898
        $day_start = intval($sday_start);
2899
        $year_end = intval($syear_end);
2900
        $month_end = intval($smonth_end);
2901
        $day_end = intval($sday_end);
2902
        $id = intval($id);
2903
        $date_start = "$year_start-".(($month_start < 10) ? "0$month_start" : $month_start)."-".(($day_start < 10) ? "0$day_start" : $day_start);
2904
        $date_end = "$year_end-".(($month_end < 10) ? "0$month_end" : $month_end)."-".(($day_end < 10) ? "0$day_end" : $day_end);
2905
2906
        if (empty($name)) {
2907
            $msg = get_lang('SessionCategoryNameIsRequired');
2908
            return $msg;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $msg returns the type string which is incompatible with the documented return type boolean.
Loading history...
2909
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
2910
            $msg = get_lang('InvalidStartDate');
2911
            return $msg;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $msg returns the type string which is incompatible with the documented return type boolean.
Loading history...
2912
        } elseif (!$month_end && !$day_end && !$year_end) {
2913
            $date_end = null;
2914
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
2915
            $msg = get_lang('InvalidEndDate');
2916
            return $msg;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $msg returns the type string which is incompatible with the documented return type boolean.
Loading history...
2917
        } elseif ($date_start >= $date_end) {
2918
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
2919
            return $msg;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $msg returns the type string which is incompatible with the documented return type boolean.
Loading history...
2920
        }
2921
        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...
2922
            $sql = "UPDATE $tbl_session_category
2923
                    SET
2924
                        name = '".Database::escape_string($name)."',
2925
                        date_start = '$date_start' ,
2926
                        date_end = '$date_end'
2927
                    WHERE id= $id";
2928
        } else {
2929
            $sql = "UPDATE $tbl_session_category SET
2930
                        name = '".Database::escape_string($name)."',
2931
                        date_start = '$date_start',
2932
                        date_end = NULL
2933
                    WHERE id= $id";
2934
        }
2935
        $result = Database::query($sql);
2936
        return ($result ? true : false);
2937
    }
2938
2939
    /**
2940
     * Delete sessions categories
2941
     * @author Jhon Hinojosa <[email protected]>, from existing code
2942
     * @param    array    id_checked
2943
     * @param    bool    include delete session
2944
     * @param    bool    optional, true if the function is called by a webservice, false otherwise.
2945
     * @return    bool    Nothing, or false on error
2946
     * The parameters is a array to delete sessions
2947
     * */
2948
    public static function delete_session_category($id_checked, $delete_session = false, $from_ws = false)
2949
    {
2950
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2951
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2952
        if (is_array($id_checked)) {
2953
            $id_checked = Database::escape_string(implode(',', $id_checked));
2954
        } else {
2955
            $id_checked = intval($id_checked);
2956
        }
2957
2958
        //Setting session_category_id to 0
2959
        $sql = "UPDATE $tbl_session SET session_category_id = NULL
2960
                WHERE session_category_id IN (".$id_checked.")";
2961
        Database::query($sql);
2962
2963
        $sql = "SELECT id FROM $tbl_session WHERE session_category_id IN (".$id_checked.")";
2964
        $result = Database::query($sql);
2965
        while ($rows = Database::fetch_array($result)) {
2966
            $session_id = $rows['id'];
2967
            if ($delete_session) {
2968
                if ($from_ws) {
2969
                    self::delete($session_id, true);
2970
                } else {
2971
                    self::delete($session_id);
2972
                }
2973
            }
2974
        }
2975
        $sql = "DELETE FROM $tbl_session_category WHERE id IN (".$id_checked.")";
2976
        Database::query($sql);
2977
2978
        // Add event to system log
2979
        $user_id = api_get_user_id();
2980
        Event::addEvent(
2981
            LOG_SESSION_CATEGORY_DELETE,
2982
            LOG_SESSION_CATEGORY_ID,
2983
            $id_checked,
2984
            api_get_utc_datetime(),
2985
            $user_id
2986
        );
2987
2988
        return true;
2989
    }
2990
2991
    /**
2992
     * Get a list of sessions of which the given conditions match with an = 'cond'
2993
     * @param  array $conditions a list of condition example :
2994
     * array('status' => STUDENT) or
2995
     * array('s.name' => array('operator' => 'LIKE', value = '%$needle%'))
2996
     * @param  array $order_by a list of fields on which sort
2997
     * @return array An array with all sessions of the platform.
2998
     * @todo   optional course code parameter, optional sorting parameters...
2999
     */
3000
    public static function get_sessions_list($conditions = [], $order_by = [], $from = null, $to = null)
3001
    {
3002
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
3003
        $session_category_table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3004
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
3005
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3006
        $session_course_table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3007
        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
3008
        $access_url_id = api_get_current_access_url_id();
3009
        $return_array = [];
3010
3011
        $sql_query = " SELECT
3012
                    DISTINCT(s.id),
3013
                    s.name,
3014
                    s.nbr_courses,
3015
                    s.access_start_date,
3016
                    s.access_end_date,
3017
                    u.firstname,
3018
                    u.lastname,
3019
                    sc.name as category_name,
3020
                    s.promotion_id
3021
				FROM $session_table s
3022
				INNER JOIN $user_table u ON s.id_coach = u.user_id
3023
				INNER JOIN $table_access_url_rel_session ar ON ar.session_id = s.id
3024
				LEFT JOIN  $session_category_table sc ON s.session_category_id = sc.id
3025
				LEFT JOIN $session_course_table sco ON (sco.session_id = s.id)
3026
				INNER JOIN $course_table c ON sco.c_id = c.id
3027
				WHERE ar.access_url_id = $access_url_id ";
3028
3029
        $availableFields = [
3030
            's.id',
3031
            's.name',
3032
            'c.id',
3033
        ];
3034
3035
        $availableOperator = [
3036
            'like',
3037
            '>=',
3038
            '<=',
3039
            '=',
3040
        ];
3041
3042
        if (count($conditions) > 0) {
3043
            foreach ($conditions as $field => $options) {
3044
                $operator = strtolower($options['operator']);
3045
                $value = Database::escape_string($options['value']);
3046
                $sql_query .= ' AND ';
3047
                if (in_array($field, $availableFields) && in_array($operator, $availableOperator)) {
3048
                    $sql_query .= $field." $operator '".$value."'";
3049
                }
3050
            }
3051
        }
3052
3053
        $orderAvailableList = ['name'];
3054
        if (count($order_by) > 0) {
3055
            $order = null;
3056
            $direction = null;
3057
            if (isset($order_by[0]) && in_array($order_by[0], $orderAvailableList)) {
3058
                $order = $order_by[0];
3059
            }
3060
            if (isset($order_by[1]) && in_array(strtolower($order_by[1]), ['desc', 'asc'])) {
3061
                $direction = $order_by[1];
3062
            }
3063
3064
            if (!empty($order)) {
3065
                $sql_query .= " ORDER BY $order $direction ";
3066
            }
3067
        }
3068
3069
        if (!is_null($from) && !is_null($to)) {
3070
            $to = intval($to);
3071
            $from = intval($from);
3072
            $sql_query .= "LIMIT $from, $to";
3073
        }
3074
3075
        $sql_result = Database::query($sql_query);
3076
        if (Database::num_rows($sql_result) > 0) {
3077
            while ($result = Database::fetch_array($sql_result)) {
3078
                $return_array[$result['id']] = $result;
3079
            }
3080
        }
3081
3082
        return $return_array;
3083
    }
3084
3085
    /**
3086
     * Get the session category information by id
3087
     * @param string session category ID
3088
     * @return mixed false if the session category does not exist, array if the session category exists
3089
     */
3090
    public static function get_session_category($id)
3091
    {
3092
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3093
        $id = intval($id);
3094
        $sql = "SELECT id, name, date_start, date_end
3095
                FROM $tbl_session_category
3096
                WHERE id= $id";
3097
        $result = Database::query($sql);
3098
        $num = Database::num_rows($result);
3099
        if ($num > 0) {
3100
            return Database::fetch_array($result);
3101
        } else {
3102
            return false;
3103
        }
3104
    }
3105
3106
    /**
3107
     * Get all session categories (filter by access_url_id)
3108
     * @return mixed false if the session category does not exist, array if the session category exists
3109
     */
3110
    public static function get_all_session_category()
3111
    {
3112
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3113
        $id = api_get_current_access_url_id();
3114
        $sql = 'SELECT * FROM '.$tbl_session_category.'
3115
                WHERE access_url_id = ' . $id.'
3116
                ORDER BY name ASC';
3117
        $result = Database::query($sql);
3118
        if (Database::num_rows($result) > 0) {
3119
            $data = Database::store_result($result, 'ASSOC');
3120
            return $data;
3121
        } else {
3122
            return false;
3123
        }
3124
    }
3125
3126
    /**
3127
     * Assign a coach to course in session with status = 2
3128
     * @param int $userId
3129
     * @param int $sessionId
3130
     * @param int $courseId
3131
     * @param bool $noCoach optional, if is true the user don't be a coach now,
3132
     * otherwise it'll assign a coach
3133
     * @return bool true if there are affected rows, otherwise false
3134
     */
3135
    public static function set_coach_to_course_session(
3136
        $userId,
3137
        $sessionId = 0,
3138
        $courseId = 0,
3139
        $noCoach = false
3140
    ) {
3141
        // Definition of variables
3142
        $userId = intval($userId);
3143
3144
        $sessionId = !empty($sessionId) ? intval($sessionId) : api_get_session_id();
3145
        $courseId = !empty($courseId) ? intval($courseId) : api_get_course_id();
3146
3147
        if (empty($sessionId) || empty($courseId) || empty($userId)) {
3148
            return false;
3149
        }
3150
3151
        // Table definition
3152
        $tblSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3153
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3154
        $tblUser = Database::get_main_table(TABLE_MAIN_USER);
3155
3156
        // check if user is a teacher
3157
        $sql = "SELECT * FROM $tblUser
3158
                WHERE status = 1 AND user_id = $userId";
3159
3160
        $rsCheckUser = Database::query($sql);
3161
3162
        if (Database::num_rows($rsCheckUser) <= 0) {
3163
            return false;
3164
        }
3165
3166
        if ($noCoach) {
3167
            // check if user_id exists in session_rel_user (if the user is
3168
            // subscribed to the session in any manner)
3169
            $sql = "SELECT user_id FROM $tblSessionRelUser
3170
                    WHERE
3171
                        session_id = $sessionId AND
3172
                        user_id = $userId";
3173
            $res = Database::query($sql);
3174
3175
            if (Database::num_rows($res) > 0) {
3176
                // The user is already subscribed to the session. Change the
3177
                // record so the user is NOT a coach for this course anymore
3178
                // and then exit
3179
                $sql = "UPDATE $tblSessionRelCourseRelUser
3180
                        SET status = 0
3181
                        WHERE
3182
                            session_id = $sessionId AND
3183
                            c_id = $courseId AND
3184
                            user_id = $userId ";
3185
                $result = Database::query($sql);
3186
3187
                return Database::affected_rows($result) > 0;
3188
            }
3189
3190
            // The user is not subscribed to the session, so make sure
3191
            // he isn't subscribed to a course in this session either
3192
            // and then exit
3193
            $sql = "DELETE FROM $tblSessionRelCourseRelUser
3194
                    WHERE
3195
                        session_id = $sessionId AND
3196
                        c_id = $courseId AND
3197
                        user_id = $userId ";
3198
            $result = Database::query($sql);
3199
3200
            return Database::affected_rows($result) > 0;
3201
        }
3202
3203
        // Assign user as a coach to course
3204
        // First check if the user is registered to the course
3205
        $sql = "SELECT user_id FROM $tblSessionRelCourseRelUser
3206
                WHERE
3207
                    session_id = $sessionId AND
3208
                    c_id = $courseId AND
3209
                    user_id = $userId";
3210
        $rs_check = Database::query($sql);
3211
3212
        // Then update or insert.
3213
        if (Database::num_rows($rs_check) > 0) {
3214
            $sql = "UPDATE $tblSessionRelCourseRelUser SET status = 2
3215
                    WHERE
3216
                        session_id = $sessionId AND
3217
                        c_id = $courseId AND
3218
                        user_id = $userId ";
3219
            $result = Database::query($sql);
3220
3221
            return Database::affected_rows($result) > 0;
3222
        }
3223
3224
        $sql = "INSERT INTO $tblSessionRelCourseRelUser(session_id, c_id, user_id, status)
3225
                VALUES($sessionId, $courseId, $userId, 2)";
3226
        $result = Database::query($sql);
3227
3228
        return Database::affected_rows($result) > 0;
3229
    }
3230
3231
    /**
3232
     * @param int $sessionId
3233
     * @return bool
3234
     */
3235
    public static function removeAllDrhFromSession($sessionId)
3236
    {
3237
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3238
        $sessionId = (int) $sessionId;
3239
3240
        if (empty($sessionId)) {
3241
            return false;
3242
        }
3243
3244
        $sql = "DELETE FROM $tbl_session_rel_user
3245
                WHERE
3246
                    session_id = $sessionId AND                            
3247
                    relation_type =".SESSION_RELATION_TYPE_RRHH;
3248
        Database::query($sql);
3249
3250
        return true;
3251
    }
3252
3253
    /**
3254
     * Subscribes sessions to human resource manager (Dashboard feature)
3255
     * @param array $userInfo Human Resource Manager info
3256
     * @param array $sessions_list Sessions id
3257
     * @param bool $sendEmail
3258
     * @param bool $removeSessionsFromUser
3259
     * @return int
3260
     * */
3261
    public static function subscribeSessionsToDrh(
3262
        $userInfo,
3263
        $sessions_list,
3264
        $sendEmail = false,
3265
        $removeSessionsFromUser = true
3266
    ) {
3267
        // Database Table Definitions
3268
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3269
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3270
3271
        if (empty($userInfo)) {
3272
            return 0;
3273
        }
3274
3275
        $userId = $userInfo['user_id'];
3276
3277
        // Only subscribe DRH users.
3278
        $rolesAllowed = [
3279
            DRH,
3280
            SESSIONADMIN,
3281
            PLATFORM_ADMIN,
3282
            COURSE_TUTOR,
3283
        ];
3284
        $isAdmin = api_is_platform_admin_by_id($userInfo['user_id']);
3285
        if (!$isAdmin && !in_array($userInfo['status'], $rolesAllowed)) {
3286
            return 0;
3287
        }
3288
3289
        $affected_rows = 0;
3290
        // Deleting assigned sessions to hrm_id.
3291
        if ($removeSessionsFromUser) {
3292
            if (api_is_multiple_url_enabled()) {
3293
                $sql = "SELECT s.session_id
3294
                        FROM $tbl_session_rel_user s
3295
                        INNER JOIN $tbl_session_rel_access_url a 
3296
                        ON (a.session_id = s.session_id)
3297
                        WHERE
3298
                            s.user_id = $userId AND
3299
                            relation_type = ".SESSION_RELATION_TYPE_RRHH." AND
3300
                            access_url_id = " . api_get_current_access_url_id();
3301
            } else {
3302
                $sql = "SELECT s.session_id 
3303
                        FROM $tbl_session_rel_user s
3304
                        WHERE user_id = $userId AND relation_type=".SESSION_RELATION_TYPE_RRHH;
3305
            }
3306
            $result = Database::query($sql);
3307
3308
            if (Database::num_rows($result) > 0) {
3309
                while ($row = Database::fetch_array($result)) {
3310
                    $sql = "DELETE FROM $tbl_session_rel_user
3311
                            WHERE
3312
                                session_id = {$row['session_id']} AND
3313
                                user_id = $userId AND
3314
                                relation_type =".SESSION_RELATION_TYPE_RRHH;
3315
                    Database::query($sql);
3316
                }
3317
            }
3318
        }
3319
3320
        // Inserting new sessions list.
3321
        if (!empty($sessions_list) && is_array($sessions_list)) {
3322
            foreach ($sessions_list as $session_id) {
3323
                $session_id = intval($session_id);
3324
                $sql = "SELECT session_id
3325
                        FROM $tbl_session_rel_user
3326
                        WHERE
3327
                            session_id = $session_id AND
3328
                            user_id = $userId AND
3329
                            relation_type = '".SESSION_RELATION_TYPE_RRHH."'";
3330
                $result = Database::query($sql);
3331
                if (Database::num_rows($result) == 0) {
3332
                    $sql = "INSERT IGNORE INTO $tbl_session_rel_user (session_id, user_id, relation_type, registered_at)
3333
                            VALUES (
3334
                                $session_id,
3335
                                $userId,
3336
                                '".SESSION_RELATION_TYPE_RRHH."',
3337
                                '".api_get_utc_datetime()."'
3338
                            )";
3339
                    Database::query($sql);
3340
                    $affected_rows++;
3341
                }
3342
            }
3343
        }
3344
3345
        return $affected_rows;
3346
    }
3347
3348
    /**
3349
     * @param int $sessionId
3350
     * @return array
3351
     */
3352
    public static function getDrhUsersInSession($sessionId)
3353
    {
3354
        return self::get_users_by_session($sessionId, SESSION_RELATION_TYPE_RRHH);
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::get_users_b...ION_RELATION_TYPE_RRHH) also could return the type integer which is incompatible with the documented return type array.
Loading history...
3355
    }
3356
3357
    /**
3358
     * @param int $userId
3359
     * @param int $sessionId
3360
     * @return array
3361
     */
3362
    public static function getSessionFollowedByDrh($userId, $sessionId)
3363
    {
3364
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3365
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3366
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3367
3368
        $userId = intval($userId);
3369
        $sessionId = intval($sessionId);
3370
3371
        $select = " SELECT * ";
3372
        if (api_is_multiple_url_enabled()) {
3373
            $sql = " $select FROM $tbl_session s
3374
                    INNER JOIN $tbl_session_rel_user sru ON (sru.session_id = s.id)
3375
                    LEFT JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
3376
                    WHERE
3377
                        sru.user_id = '$userId' AND
3378
                        sru.session_id = '$sessionId' AND
3379
                        sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."' AND
3380
                        access_url_id = " . api_get_current_access_url_id()."
3381
                        ";
3382
        } else {
3383
            $sql = "$select FROM $tbl_session s
3384
                     INNER JOIN $tbl_session_rel_user sru
3385
                     ON
3386
                        sru.session_id = s.id AND
3387
                        sru.user_id = '$userId' AND
3388
                        sru.session_id = '$sessionId' AND
3389
                        sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."'
3390
                    ";
3391
        }
3392
3393
        $result = Database::query($sql);
3394
        if (Database::num_rows($result)) {
3395
            $row = Database::fetch_array($result, 'ASSOC');
3396
            $row['course_list'] = self::get_course_list_by_session_id($sessionId);
3397
3398
            return $row;
3399
        }
3400
3401
        return [];
3402
    }
3403
3404
    /**
3405
     * Get sessions followed by human resources manager
3406
     * @param int $userId
3407
     * @param int $start
3408
     * @param int $limit
3409
     * @param bool $getCount
3410
     * @param bool $getOnlySessionId
3411
     * @param bool $getSql
3412
     * @param string $orderCondition
3413
     * @param string $keyword
3414
     * @param string $description
3415
     *
3416
     * @return array sessions
3417
     */
3418
    public static function get_sessions_followed_by_drh(
3419
        $userId,
3420
        $start = null,
3421
        $limit = null,
3422
        $getCount = false,
3423
        $getOnlySessionId = false,
3424
        $getSql = false,
3425
        $orderCondition = null,
3426
        $keyword = '',
3427
        $description = ''
3428
    ) {
3429
        return self::getSessionsFollowedByUser(
3430
            $userId,
3431
            DRH,
3432
            $start,
3433
            $limit,
3434
            $getCount,
3435
            $getOnlySessionId,
3436
            $getSql,
3437
            $orderCondition,
3438
            $keyword,
3439
            $description
3440
        );
3441
    }
3442
3443
    /**
3444
     * Get sessions followed by human resources manager
3445
     * @param int $userId
3446
     * @param int $status DRH Optional
3447
     * @param int $start
3448
     * @param int $limit
3449
     * @param bool $getCount
3450
     * @param bool $getOnlySessionId
3451
     * @param bool $getSql
3452
     * @param string $orderCondition
3453
     * @param string $keyword
3454
     * @param string $description
3455
     * @return array sessions
3456
     */
3457
    public static function getSessionsFollowedByUser(
3458
        $userId,
3459
        $status = null,
3460
        $start = null,
3461
        $limit = null,
3462
        $getCount = false,
3463
        $getOnlySessionId = false,
3464
        $getSql = false,
3465
        $orderCondition = null,
3466
        $keyword = '',
3467
        $description = ''
3468
    ) {
3469
        // Database Table Definitions
3470
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3471
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3472
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3473
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3474
3475
        $userId = (int) $userId;
3476
3477
        $select = " SELECT DISTINCT * ";
3478
        if ($getCount) {
3479
            $select = " SELECT count(DISTINCT(s.id)) as count ";
3480
        }
3481
3482
        if ($getOnlySessionId) {
3483
            $select = " SELECT DISTINCT(s.id) ";
3484
        }
3485
3486
        $limitCondition = null;
3487
        if (!is_null($start) && !is_null($limit)) {
3488
            $limitCondition = " LIMIT ".intval($start).", ".intval($limit);
3489
        }
3490
3491
        if (empty($orderCondition)) {
3492
            $orderCondition = " ORDER BY s.name ";
3493
        }
3494
3495
        $whereConditions = null;
3496
        $sessionCourseConditions = null;
3497
        $sessionConditions = null;
3498
        $sessionQuery = '';
3499
        $courseSessionQuery = null;
3500
3501
        switch ($status) {
3502
            case DRH:
3503
                $sessionQuery = "SELECT sru.session_id
3504
                                 FROM
3505
                                 $tbl_session_rel_user sru
3506
                                 WHERE
3507
                                    sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."' AND
3508
                                    sru.user_id = $userId";
3509
                break;
3510
            case COURSEMANAGER:
3511
                $courseSessionQuery = "
3512
                    SELECT scu.session_id as id
3513
                    FROM $tbl_session_rel_course_rel_user scu
3514
                    WHERE (scu.status = 2 AND scu.user_id = $userId)";
3515
3516
                $whereConditions = " OR (s.id_coach = $userId) ";
3517
                break;
3518
            default:
3519
                $sessionQuery = "SELECT sru.session_id
3520
                                 FROM
3521
                                 $tbl_session_rel_user sru
3522
                                 WHERE
3523
                                    sru.user_id = $userId";
3524
                break;
3525
        }
3526
3527
        $keywordCondition = '';
3528
        if (!empty($keyword)) {
3529
            $keyword = Database::escape_string($keyword);
3530
            $keywordCondition = " AND (s.name LIKE '%$keyword%' ) ";
3531
3532
            if (!empty($description)) {
3533
                $description = Database::escape_string($description);
3534
                $keywordCondition = " AND (s.name LIKE '%$keyword%' OR s.description LIKE '%$description%' ) ";
3535
            }
3536
        }
3537
3538
        $whereConditions .= $keywordCondition;
3539
        $subQuery = $sessionQuery.$courseSessionQuery;
3540
3541
        $sql = " $select FROM $tbl_session s
3542
                INNER JOIN $tbl_session_rel_access_url a 
3543
                ON (s.id = a.session_id)
3544
                WHERE
3545
                    access_url_id = ".api_get_current_access_url_id()." AND
3546
                    s.id IN (
3547
                        $subQuery
3548
                    )
3549
                    $whereConditions
3550
                    $orderCondition
3551
                    $limitCondition";
3552
3553
        if ($getSql) {
3554
            return $sql;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $sql returns the type string which is incompatible with the documented return type array.
Loading history...
3555
        }
3556
        $result = Database::query($sql);
3557
3558
        if ($getCount) {
3559
            $row = Database::fetch_array($result);
3560
            return $row['count'];
3561
        }
3562
3563
        $sessions = [];
3564
        if (Database::num_rows($result) > 0) {
3565
            $sysUploadPath = api_get_path(SYS_UPLOAD_PATH).'sessions/';
3566
            $webUploadPath = api_get_path(WEB_UPLOAD_PATH).'sessions/';
3567
            $imgPath = Display::return_icon(
3568
                'session_default_small.png',
3569
                null,
3570
                [],
3571
                ICON_SIZE_SMALL,
3572
                false,
3573
                true
3574
            );
3575
3576
            while ($row = Database::fetch_array($result)) {
3577
                if ($getOnlySessionId) {
3578
                    $sessions[$row['id']] = $row;
3579
                    continue;
3580
                }
3581
                $imageFilename = \ExtraField::FIELD_TYPE_FILE_IMAGE.'_'.$row['id'].'.png';
3582
                $row['image'] = is_file($sysUploadPath.$imageFilename) ? $webUploadPath.$imageFilename : $imgPath;
3583
3584
                if ($row['display_start_date'] == '0000-00-00 00:00:00' || $row['display_start_date'] == '0000-00-00') {
3585
                    $row['display_start_date'] = null;
3586
                }
3587
3588
                if ($row['display_end_date'] == '0000-00-00 00:00:00' || $row['display_end_date'] == '0000-00-00') {
3589
                    $row['display_end_date'] = null;
3590
                }
3591
3592
                if ($row['access_start_date'] == '0000-00-00 00:00:00' || $row['access_start_date'] == '0000-00-00') {
3593
                    $row['access_start_date'] = null;
3594
                }
3595
3596
                if ($row['access_end_date'] == '0000-00-00 00:00:00' || $row['access_end_date'] == '0000-00-00') {
3597
                    $row['access_end_date'] = null;
3598
                }
3599
3600
                if (
3601
                    $row['coach_access_start_date'] == '0000-00-00 00:00:00' ||
3602
                    $row['coach_access_start_date'] == '0000-00-00'
3603
                ) {
3604
                    $row['coach_access_start_date'] = null;
3605
                }
3606
3607
                if (
3608
                    $row['coach_access_end_date'] == '0000-00-00 00:00:00' ||
3609
                    $row['coach_access_end_date'] == '0000-00-00'
3610
                ) {
3611
                    $row['coach_access_end_date'] = null;
3612
                }
3613
3614
                $sessions[$row['id']] = $row;
3615
            }
3616
        }
3617
3618
        return $sessions;
3619
    }
3620
3621
    /**
3622
     * Gets the list (or the count) of courses by session filtered by access_url
3623
     * @param int $session_id The session id
3624
     * @param string $course_name The course code
3625
     * @param string $orderBy Field to order the data
3626
     * @param boolean $getCount Optional. Count the session courses
3627
     * @return array|int List of courses. Whether $getCount is true, return the count
3628
     */
3629
    public static function get_course_list_by_session_id(
3630
        $session_id,
3631
        $course_name = '',
3632
        $orderBy = null,
3633
        $getCount = false
3634
    ) {
3635
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3636
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3637
        $session_id = intval($session_id);
3638
        $sqlSelect = "*, c.id, c.id as real_id";
3639
3640
        if ($getCount) {
3641
            $sqlSelect = "COUNT(1) as count";
3642
        }
3643
3644
        // select the courses
3645
        $sql = "SELECT $sqlSelect
3646
                FROM $tbl_course c
3647
                INNER JOIN $tbl_session_rel_course src
3648
                ON (c.id = src.c_id)
3649
		        WHERE src.session_id = '$session_id' ";
3650
3651
        if (!empty($course_name)) {
3652
            $course_name = Database::escape_string($course_name);
3653
            $sql .= " AND c.title LIKE '%$course_name%' ";
3654
        }
3655
3656
        if (!empty($orderBy)) {
3657
            $orderBy = Database::escape_string($orderBy);
3658
            $orderBy = " ORDER BY $orderBy";
3659
        } else {
3660
            if (self::orderCourseIsEnabled()) {
3661
                $orderBy .= " ORDER BY position ";
3662
            } else {
3663
                $orderBy .= " ORDER BY title ";
3664
            }
3665
        }
3666
3667
        $sql .= Database::escape_string($orderBy);
3668
        $result = Database::query($sql);
3669
        $num_rows = Database::num_rows($result);
3670
        $courses = [];
3671
        if ($num_rows > 0) {
3672
            if ($getCount) {
3673
                $count = Database::fetch_assoc($result);
3674
3675
                return intval($count['count']);
3676
            }
3677
3678
            while ($row = Database::fetch_array($result, 'ASSOC')) {
3679
                $courses[$row['real_id']] = $row;
3680
            }
3681
        }
3682
3683
        return $courses;
3684
    }
3685
3686
    /**
3687
     * Gets the list of courses by session filtered by access_url
3688
     *
3689
     * @param $userId
3690
     * @param $sessionId
3691
     * @param null $from
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $from is correct as it would always require null to be passed?
Loading history...
Documentation Bug introduced by
Are you sure the doc-type for parameter $column is correct as it would always require null to be passed?
Loading history...
Documentation Bug introduced by
Are you sure the doc-type for parameter $limit is correct as it would always require null to be passed?
Loading history...
Documentation Bug introduced by
Are you sure the doc-type for parameter $direction is correct as it would always require null to be passed?
Loading history...
3692
     * @param null $limit
3693
     * @param null $column
3694
     * @param null $direction
3695
     * @param bool $getCount
3696
     * @param string $keyword
3697
     * @return array
3698
     */
3699
    public static function getAllCoursesFollowedByUser(
3700
        $userId,
3701
        $sessionId,
3702
        $from = null,
3703
        $limit = null,
3704
        $column = null,
3705
        $direction = null,
3706
        $getCount = false,
3707
        $keyword = ''
3708
    ) {
3709
        if (empty($sessionId)) {
3710
            $sessionsSQL = self::get_sessions_followed_by_drh(
3711
                $userId,
3712
                null,
3713
                null,
3714
                null,
3715
                true,
3716
                true
3717
            );
3718
        } else {
3719
            $sessionsSQL = intval($sessionId);
3720
        }
3721
3722
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3723
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3724
3725
        if ($getCount) {
3726
            $select = "SELECT COUNT(DISTINCT(c.code)) as count ";
3727
        } else {
3728
            $select = "SELECT DISTINCT c.* ";
3729
        }
3730
3731
        $keywordCondition = null;
3732
        if (!empty($keyword)) {
3733
            $keyword = Database::escape_string($keyword);
3734
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
3735
        }
3736
3737
        // Select the courses
3738
        $sql = "$select
3739
                FROM $tbl_course c
3740
                INNER JOIN $tbl_session_rel_course src
3741
                ON c.id = src.c_id
3742
		        WHERE
3743
		            src.session_id IN ($sessionsSQL)
3744
		            $keywordCondition
3745
		        ";
3746
        if ($getCount) {
3747
            $result = Database::query($sql);
3748
            $row = Database::fetch_array($result, 'ASSOC');
3749
            return $row['count'];
3750
        }
3751
3752
        if (isset($from) && isset($limit)) {
3753
            $from = intval($from);
3754
            $limit = intval($limit);
3755
            $sql .= " LIMIT $from, $limit";
3756
        }
3757
3758
        $result = Database::query($sql);
3759
        $num_rows = Database::num_rows($result);
3760
        $courses = [];
3761
3762
        if ($num_rows > 0) {
3763
            while ($row = Database::fetch_array($result, 'ASSOC')) {
3764
                $courses[$row['id']] = $row;
3765
            }
3766
        }
3767
3768
        return $courses;
3769
    }
3770
3771
    /**
3772
     * Gets the list of courses by session filtered by access_url
3773
     * @param int $session_id
3774
     * @param string $course_name
3775
     * @return array list of courses
3776
     */
3777
    public static function get_course_list_by_session_id_like($session_id, $course_name = '')
3778
    {
3779
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3780
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3781
3782
        $session_id = intval($session_id);
3783
        $course_name = Database::escape_string($course_name);
3784
3785
        // select the courses
3786
        $sql = "SELECT c.id, c.title FROM $tbl_course c
3787
                INNER JOIN $tbl_session_rel_course src
3788
                ON c.id = src.c_id
3789
		        WHERE ";
3790
3791
        if (!empty($session_id)) {
3792
            $sql .= "src.session_id LIKE '$session_id' AND ";
3793
        }
3794
3795
        if (!empty($course_name)) {
3796
            $sql .= "UPPER(c.title) LIKE UPPER('%$course_name%') ";
3797
        }
3798
3799
        $sql .= "ORDER BY title;";
3800
        $result = Database::query($sql);
3801
        $num_rows = Database::num_rows($result);
3802
        $courses = [];
3803
        if ($num_rows > 0) {
3804
            while ($row = Database::fetch_array($result, 'ASSOC')) {
3805
                $courses[$row['id']] = $row;
3806
            }
3807
        }
3808
3809
        return $courses;
3810
    }
3811
3812
    /**
3813
     * Gets the count of courses by session filtered by access_url
3814
     * @param int session id
3815
     * @param string $keyword
3816
     * @return array list of courses
3817
     */
3818
    public static function getCourseCountBySessionId($session_id, $keyword = '')
3819
    {
3820
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3821
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3822
        $session_id = intval($session_id);
3823
3824
        // select the courses
3825
        $sql = "SELECT COUNT(c.code) count
3826
                FROM $tbl_course c
3827
                INNER JOIN $tbl_session_rel_course src
3828
                ON c.id = src.c_id
3829
		        WHERE src.session_id = '$session_id' ";
3830
3831
        $keywordCondition = null;
3832
        if (!empty($keyword)) {
3833
            $keyword = Database::escape_string($keyword);
3834
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
3835
        }
3836
        $sql .= $keywordCondition;
3837
3838
        $result = Database::query($sql);
3839
        $num_rows = Database::num_rows($result);
3840
        if ($num_rows > 0) {
3841
            $row = Database::fetch_array($result, 'ASSOC');
3842
            return $row['count'];
3843
        }
3844
3845
        return null;
3846
    }
3847
3848
    /**
3849
     * Get the session id based on the original id and field name in the extra fields.
3850
     * Returns 0 if session was not found
3851
     *
3852
     * @param string $value Original session id
3853
     * @param string $variable Original field name
3854
     * @return int Session id
3855
     */
3856
    public static function getSessionIdFromOriginalId($value, $variable)
3857
    {
3858
        $extraFieldValue = new ExtraFieldValue('session');
3859
        $result = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
3860
            $variable,
3861
            $value
3862
        );
3863
3864
        if (!empty($result)) {
3865
            return $result['item_id'];
3866
        }
3867
3868
        return 0;
3869
    }
3870
3871
    /**
3872
     * Get users by session
3873
     * @param  int $id session id
3874
     * @param    int $status filter by status coach = 2
3875
     * @param bool $getCount Optional. Allow get the number of rows from the result
3876
     * @param int $urlId
3877
     * @return array|int A list with an user list. If $getCount is true then return a the count of registers
3878
     */
3879
    public static function get_users_by_session(
3880
        $id,
3881
        $status = null,
3882
        $getCount = false,
3883
        $urlId = 0
3884
    ) {
3885
        if (empty($id)) {
3886
            return [];
3887
        }
3888
        $id = intval($id);
3889
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
3890
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3891
        $table_access_url_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
3892
3893
        $selectedField = '
3894
            u.user_id, u.lastname, u.firstname, u.username, su.relation_type, au.access_url_id,
3895
            su.moved_to, su.moved_status, su.moved_at
3896
        ';
3897
3898
        if ($getCount) {
3899
            $selectedField = 'count(1) AS count';
3900
        }
3901
3902
        $sql = "SELECT $selectedField
3903
                FROM $tbl_user u
3904
                INNER JOIN $tbl_session_rel_user su
3905
                ON u.user_id = su.user_id AND
3906
                su.session_id = $id
3907
                LEFT OUTER JOIN $table_access_url_user au
3908
                ON (au.user_id = u.user_id)
3909
                ";
3910
3911
        $urlId = empty($urlId) ? api_get_current_access_url_id() : (int) $urlId;
3912
3913
        if ($status != '') {
3914
            $status = intval($status);
3915
            $sql .= " WHERE su.relation_type = $status AND (au.access_url_id = $urlId OR au.access_url_id is null)";
3916
        } else {
3917
            $sql .= " WHERE (au.access_url_id = $urlId OR au.access_url_id is null )";
3918
        }
3919
3920
        $sql .= " ORDER BY su.relation_type, ";
3921
        $sql .= api_sort_by_first_name() ? ' u.firstname, u.lastname' : '  u.lastname, u.firstname';
3922
3923
        $result = Database::query($sql);
3924
        if ($getCount) {
3925
            $count = Database::fetch_assoc($result);
3926
3927
            return $count['count'];
3928
        }
3929
3930
        $return = [];
3931
        while ($row = Database::fetch_array($result, 'ASSOC')) {
3932
            $return[] = $row;
3933
        }
3934
3935
        return $return;
3936
    }
3937
3938
    /**
3939
     * The general coach (field: session.id_coach)
3940
     * @param int $user_id user id
3941
     * @param boolean   $asPlatformAdmin The user is platform admin, return everything
3942
     * @return array
3943
     */
3944
    public static function get_sessions_by_general_coach($user_id, $asPlatformAdmin = false)
3945
    {
3946
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
3947
        $user_id = intval($user_id);
3948
3949
        // Session where we are general coach
3950
        $sql = "SELECT DISTINCT *
3951
                FROM $session_table";
3952
3953
        if (!$asPlatformAdmin) {
3954
            $sql .= " WHERE id_coach = $user_id";
3955
        }
3956
3957
        if (api_is_multiple_url_enabled()) {
3958
            $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3959
            $access_url_id = api_get_current_access_url_id();
3960
3961
            $sqlCoach = '';
3962
            if (!$asPlatformAdmin) {
3963
                $sqlCoach = " id_coach = $user_id AND ";
3964
            }
3965
3966
            if ($access_url_id != -1) {
3967
                $sql = 'SELECT DISTINCT session.*
3968
                    FROM ' . $session_table.' session INNER JOIN '.$tbl_session_rel_access_url.' session_rel_url
3969
                    ON (session.id = session_rel_url.session_id)
3970
                    WHERE '.$sqlCoach.' access_url_id = '.$access_url_id;
3971
            }
3972
        }
3973
        $sql .= ' ORDER by name';
3974
        $result = Database::query($sql);
3975
3976
        return Database::store_result($result, 'ASSOC');
3977
    }
3978
3979
    /**
3980
     * @param int $user_id
3981
     * @return array
3982
     * @deprecated use get_sessions_by_general_coach()
3983
     */
3984
    public static function get_sessions_by_coach($user_id)
3985
    {
3986
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
3987
3988
        return Database::select(
3989
            '*',
3990
            $session_table,
3991
            ['where' => ['id_coach = ?' => $user_id]]
3992
        );
3993
    }
3994
3995
    /**
3996
     * @param int $user_id
3997
     * @param int $courseId
3998
     * @param int $session_id
3999
     * @return array|bool
4000
     */
4001
    public static function get_user_status_in_course_session($user_id, $courseId, $session_id)
4002
    {
4003
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
4004
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
4005
        $sql = "SELECT session_rcru.status
4006
                FROM $table session_rcru 
4007
                INNER JOIN $tbl_user user
4008
                ON (session_rcru.user_id = user.user_id)
4009
                WHERE                    
4010
                    session_rcru.session_id = '".intval($session_id)."' AND
4011
                    session_rcru.c_id ='" . intval($courseId)."' AND
4012
                    user.user_id = " . intval($user_id);
4013
4014
        $result = Database::query($sql);
4015
        $status = false;
4016
        if (Database::num_rows($result)) {
4017
            $status = Database::fetch_row($result);
4018
            $status = $status['0'];
4019
        }
4020
4021
        return $status;
4022
    }
4023
4024
    /**
4025
     * Gets user status within a session
4026
     *
4027
     * @param int $userId
4028
     * @param int $sessionId
4029
     *
4030
     * @return SessionRelUser
4031
     */
4032
    public static function getUserStatusInSession($userId, $sessionId)
4033
    {
4034
        $em = Database::getManager();
4035
        $subscriptions = $em
4036
            ->getRepository('ChamiloCoreBundle:SessionRelUser')
4037
            ->findBy(['session' => $sessionId, 'user' => $userId]);
4038
4039
        /** @var SessionRelUser $subscription */
4040
        $subscription = current($subscriptions);
4041
4042
        return $subscription;
4043
    }
4044
4045
    /**
4046
     * @param int $id
4047
     * @return array
4048
     */
4049
    public static function get_all_sessions_by_promotion($id)
4050
    {
4051
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
4052
4053
        return Database::select(
4054
            '*',
4055
            $table,
4056
            ['where' => ['promotion_id = ?' => $id]]
4057
        );
4058
    }
4059
4060
    /**
4061
     * @param int $promotion_id
4062
     * @param array $list
4063
     */
4064
    public static function subscribe_sessions_to_promotion($promotion_id, $list)
4065
    {
4066
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
4067
        $params = [];
4068
        $params['promotion_id'] = 0;
4069
        Database::update(
4070
            $table,
4071
            $params,
4072
            ['promotion_id = ?' => $promotion_id]
4073
        );
4074
4075
        $params['promotion_id'] = $promotion_id;
4076
        if (!empty($list)) {
4077
            foreach ($list as $session_id) {
4078
                $session_id = intval($session_id);
4079
                Database::update($table, $params, ['id = ?' => $session_id]);
4080
            }
4081
        }
4082
    }
4083
4084
    /**
4085
     * Updates a session status
4086
     * @param	int 	session id
4087
     * @param	int 	status
4088
     */
4089
    public static function set_session_status($session_id, $status)
4090
    {
4091
        $t = Database::get_main_table(TABLE_MAIN_SESSION);
4092
        $params['visibility'] = $status;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$params was never initialized. Although not strictly required by PHP, it is generally a good practice to add $params = array(); before regardless.
Loading history...
4093
        Database::update($t, $params, ['id = ?' => $session_id]);
4094
    }
4095
4096
    /**
4097
     * Copies a session with the same data to a new session.
4098
     * The new copy is not assigned to the same promotion. @see subscribe_sessions_to_promotions() for that
4099
     * @param   int     Session ID
4100
     * @param   bool    Whether to copy the relationship with courses
4101
     * @param   bool    Whether to copy the relationship with users
4102
     * @param   bool    New courses will be created
4103
     * @param   bool    Whether to set exercises and learning paths in the new session to invisible by default
4104
     * @return  int     The new session ID on success, 0 otherwise
4105
     * @todo make sure the extra session fields are copied too
4106
     */
4107
    public static function copy(
4108
        $id,
4109
        $copy_courses = true,
4110
        $copy_users = true,
4111
        $create_new_courses = false,
4112
        $set_exercises_lp_invisible = false
4113
    ) {
4114
        $id = intval($id);
4115
        $s = self::fetch($id);
4116
        // Check all dates before copying
4117
        // Get timestamp for now in UTC - see http://php.net/manual/es/function.time.php#117251
4118
        $now = time() - date('Z');
4119
        // Timestamp in one month
4120
        $inOneMonth = $now + (30 * 24 * 3600);
4121
        $inOneMonth = api_get_local_time($inOneMonth);
4122
        if (api_strtotime($s['access_start_date']) < $now) {
4123
            $s['access_start_date'] = api_get_local_time($now);
4124
        }
4125
        if (api_strtotime($s['display_start_date']) < $now) {
4126
            $s['display_start_date'] = api_get_local_time($now);
4127
        }
4128
        if (api_strtotime($s['coach_access_start_date']) < $now) {
4129
            $s['coach_access_start_date'] = api_get_local_time($now);
4130
        }
4131
        if (api_strtotime($s['access_end_date']) < $now) {
4132
            $s['access_end_date'] = $inOneMonth;
4133
        }
4134
        if (api_strtotime($s['display_end_date']) < $now) {
4135
            $s['display_end_date'] = $inOneMonth;
4136
        }
4137
        if (api_strtotime($s['coach_access_end_date']) < $now) {
4138
            $s['coach_access_end_date'] = $inOneMonth;
4139
        }
4140
        // Now try to create the session
4141
        $sid = self::create_session(
4142
            $s['name'].' '.get_lang('CopyLabelSuffix'),
4143
            $s['access_start_date'],
4144
            $s['access_end_date'],
4145
            $s['display_start_date'],
4146
            $s['display_end_date'],
4147
            $s['coach_access_start_date'],
4148
            $s['coach_access_end_date'],
4149
            (int) $s['id_coach'],
4150
            $s['session_category_id'],
4151
            (int) $s['visibility'],
4152
            true
4153
        );
4154
4155
        if (!is_numeric($sid) || empty($sid)) {
4156
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type integer.
Loading history...
4157
        }
4158
4159
        if ($copy_courses) {
4160
            // Register courses from the original session to the new session
4161
            $courses = self::get_course_list_by_session_id($id);
4162
4163
            $short_courses = $new_short_courses = [];
4164
            if (is_array($courses) && count($courses) > 0) {
4165
                foreach ($courses as $course) {
4166
                    $short_courses[] = $course;
4167
                }
4168
            }
4169
4170
            $courses = null;
4171
            // We will copy the current courses of the session to new courses
4172
            if (!empty($short_courses)) {
4173
                if ($create_new_courses) {
4174
                    //Just in case
4175
                    if (function_exists('ini_set')) {
4176
                        api_set_memory_limit('256M');
4177
                        ini_set('max_execution_time', 0);
4178
                    }
4179
                    $params = [];
4180
                    $params['skip_lp_dates'] = true;
4181
4182
                    foreach ($short_courses as $course_data) {
4183
                        $course_info = CourseManager::copy_course_simple(
4184
                            $course_data['title'].' '.get_lang(
4185
                                'CopyLabelSuffix'
4186
                            ),
4187
                            $course_data['course_code'],
4188
                            $id,
4189
                            $sid,
4190
                            $params
4191
                        );
4192
4193
                        if ($course_info) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $course_info of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
4194
                            //By default new elements are invisible
4195
                            if ($set_exercises_lp_invisible) {
4196
                                $list = new LearnpathList('', $course_info['code'], $sid);
4197
                                $flat_list = $list->get_flat_list();
4198
                                if (!empty($flat_list)) {
4199
                                    foreach ($flat_list as $lp_id => $data) {
4200
                                        api_item_property_update(
4201
                                            $course_info,
4202
                                            TOOL_LEARNPATH,
4203
                                            $lp_id,
4204
                                            'invisible',
4205
                                            api_get_user_id(),
4206
                                            0,
4207
                                            0,
4208
                                            0,
4209
                                            0,
4210
                                            $sid
4211
                                        );
4212
                                    }
4213
                                }
4214
                                $quiz_table = Database::get_course_table(TABLE_QUIZ_TEST);
4215
                                $course_id = $course_info['real_id'];
4216
                                //@todo check this query
4217
                                $sql = "UPDATE $quiz_table SET active = 0
4218
                                        WHERE c_id = $course_id AND session_id = $sid";
4219
                                Database::query($sql);
4220
                            }
4221
                            $new_short_courses[] = $course_info['real_id'];
4222
                        }
4223
                    }
4224
                } else {
4225
                    foreach ($short_courses as $course_data) {
4226
                        $new_short_courses[] = $course_data['id'];
4227
                    }
4228
                }
4229
4230
                $short_courses = $new_short_courses;
4231
                self::add_courses_to_session($sid, $short_courses, true);
0 ignored issues
show
Bug introduced by
It seems like $sid can also be of type string; however, parameter $sessionId of SessionManager::add_courses_to_session() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4231
                self::add_courses_to_session(/** @scrutinizer ignore-type */ $sid, $short_courses, true);
Loading history...
4232
                $short_courses = null;
4233
            }
4234
        }
4235
        if ($copy_users) {
4236
            // Register users from the original session to the new session
4237
            $users = self::get_users_by_session($id);
4238
            $short_users = [];
4239
            if (is_array($users) && count($users) > 0) {
4240
                foreach ($users as $user) {
4241
                    $short_users[] = $user['user_id'];
4242
                }
4243
            }
4244
            $users = null;
4245
            //Subscribing in read only mode
4246
            self::subscribe_users_to_session(
4247
                $sid,
0 ignored issues
show
Bug introduced by
It seems like $sid can also be of type string; however, parameter $id_session of SessionManager::subscribe_users_to_session() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4247
                /** @scrutinizer ignore-type */ $sid,
Loading history...
4248
                $short_users,
4249
                SESSION_VISIBLE_READ_ONLY,
4250
                true
4251
            );
4252
            $short_users = null;
4253
        }
4254
        return $sid;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $sid also could return the type string which is incompatible with the documented return type integer.
Loading history...
4255
    }
4256
4257
    /**
4258
     * @param int $user_id
4259
     * @param int $session_id
4260
     * @return bool
4261
     */
4262
    public static function user_is_general_coach($user_id, $session_id)
4263
    {
4264
        $session_id = intval($session_id);
4265
        $user_id = intval($user_id);
4266
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
4267
        $sql = "SELECT DISTINCT id
4268
	         	FROM $session_table
4269
	         	WHERE session.id_coach =  '".$user_id."' AND id = '$session_id'";
4270
        $result = Database::query($sql);
4271
        if ($result && Database::num_rows($result)) {
4272
            return true;
4273
        }
4274
        return false;
4275
    }
4276
4277
    /**
4278
     * Get the number of sessions
4279
     * @param  int ID of the URL we want to filter on (optional)
4280
     * @return int Number of sessions
4281
     */
4282
    public static function count_sessions($access_url_id = null)
4283
    {
4284
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
4285
        $access_url_rel_session_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4286
        $sql = "SELECT count(id) FROM $session_table s";
4287
        if (!empty($access_url_id) && $access_url_id == intval($access_url_id)) {
4288
            $sql .= ", $access_url_rel_session_table u ".
4289
                " WHERE s.id = u.session_id AND u.access_url_id = $access_url_id";
4290
        }
4291
        $res = Database::query($sql);
4292
        $row = Database::fetch_row($res);
4293
        return $row[0];
4294
    }
4295
4296
    /**
4297
     * Protect a session to be edited.
4298
     * @param int $id
4299
     * @param bool $checkSession
4300
     * @return mixed | bool true if pass the check, api_not_allowed otherwise
4301
     */
4302
    public static function protectSession($id, $checkSession = true)
4303
    {
4304
        if (self::allowToManageSessions()) {
4305
            if (api_is_platform_admin() && self::allowed($id)) {
4306
                return true;
4307
            }
4308
4309
            if ($checkSession) {
4310
                if (self::allowed($id)) {
4311
                    return true;
4312
                } else {
4313
                    api_not_allowed(true);
4314
                }
4315
            }
4316
        } else {
4317
            api_not_allowed(true);
4318
        }
4319
    }
4320
4321
    /**
4322
     * @param int $id
4323
     * @return bool
4324
     */
4325
    private static function allowed($id)
4326
    {
4327
        $sessionInfo = self::fetch($id);
4328
4329
        if (empty($sessionInfo)) {
4330
            return false;
4331
        }
4332
4333
        if (api_is_platform_admin()) {
4334
            return true;
4335
        }
4336
4337
        $userId = api_get_user_id();
4338
4339
        if (api_is_session_admin() &&
4340
            api_get_setting('allow_session_admins_to_manage_all_sessions') != 'true'
4341
        ) {
4342
            if ($sessionInfo['session_admin_id'] != $userId) {
4343
                return false;
4344
            }
4345
        }
4346
4347
        if (api_is_teacher() &&
4348
            api_get_setting('allow_teachers_to_create_sessions') == 'true'
4349
        ) {
4350
            if ($sessionInfo['id_coach'] != $userId) {
4351
                return false;
4352
            }
4353
        }
4354
4355
        return true;
4356
    }
4357
4358
    /**
4359
     * @return bool
4360
     */
4361
    public static function allowToManageSessions()
4362
    {
4363
        if (self::allowManageAllSessions()) {
4364
            return true;
4365
        }
4366
4367
        $setting = api_get_setting('allow_teachers_to_create_sessions');
4368
4369
        if (api_is_teacher() && $setting == 'true') {
4370
            return true;
4371
        }
4372
4373
        return false;
4374
    }
4375
4376
    /**
4377
     * @return bool
4378
     */
4379
    public static function allowOnlyMySessions()
4380
    {
4381
        if (self::allowToManageSessions() &&
4382
            !api_is_platform_admin() &&
4383
            api_is_teacher()
4384
        ) {
4385
            return true;
4386
        }
4387
4388
        return false;
4389
    }
4390
4391
    /**
4392
     * @return bool
4393
     */
4394
    public static function allowManageAllSessions()
4395
    {
4396
        if (api_is_platform_admin() || api_is_session_admin()) {
4397
            return true;
4398
        }
4399
4400
        return false;
4401
    }
4402
4403
    /**
4404
     * @param $id
4405
     * @return bool
4406
     */
4407
    public static function protect_teacher_session_edit($id)
4408
    {
4409
        if (!api_is_coach($id) && !api_is_platform_admin()) {
4410
            api_not_allowed(true);
4411
        } else {
4412
            return true;
4413
        }
4414
    }
4415
4416
    /**
4417
     * @param int $courseId
4418
     * @return array
4419
     */
4420
    public static function get_session_by_course($courseId)
4421
    {
4422
        $table_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4423
        $table_session = Database::get_main_table(TABLE_MAIN_SESSION);
4424
        $url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4425
        $courseId = intval($courseId);
4426
        $urlId = api_get_current_access_url_id();
4427
4428
        if (empty($courseId)) {
4429
            return [];
4430
        }
4431
4432
        $sql = "SELECT name, s.id
4433
                FROM $table_session_course sc
4434
                INNER JOIN $table_session s 
4435
                ON (sc.session_id = s.id)
4436
                INNER JOIN $url u
4437
                ON (u.session_id = s.id)
4438
                WHERE 
4439
                    u.access_url_id = $urlId AND 
4440
                    sc.c_id = '$courseId' ";
4441
        $result = Database::query($sql);
4442
4443
        return Database::store_result($result);
4444
    }
4445
4446
    /**
4447
     * @param int $user_id
4448
     * @param bool $ignoreVisibilityForAdmins
4449
     * @param bool $ignoreTimeLimit
4450
     *
4451
     * @return array
4452
     */
4453
    public static function get_sessions_by_user(
4454
        $user_id,
4455
        $ignoreVisibilityForAdmins = false,
4456
        $ignoreTimeLimit = false
4457
    ) {
4458
        $sessionCategories = UserManager::get_sessions_by_category(
4459
            $user_id,
4460
            false,
4461
            $ignoreVisibilityForAdmins,
4462
            $ignoreTimeLimit
4463
        );
4464
4465
        $sessionArray = [];
4466
        if (!empty($sessionCategories)) {
4467
            foreach ($sessionCategories as $category) {
4468
                if (isset($category['sessions'])) {
4469
                    foreach ($category['sessions'] as $session) {
4470
                        $sessionArray[] = $session;
4471
                    }
4472
                }
4473
            }
4474
        }
4475
4476
        return $sessionArray;
4477
    }
4478
4479
    /**
4480
     * @param string $file
4481
     * @param bool $updateSession options:
4482
     *  true: if the session exists it will be updated.
4483
     *  false: if session exists a new session will be created adding a counter session1, session2, etc
4484
     * @param int $defaultUserId
4485
     * @param mixed $logger
4486
     * @param array $extraFields convert a file row to an extra field. Example in CSV file there's a SessionID then it will
4487
     * converted to extra_external_session_id if you set this: array('SessionId' => 'extra_external_session_id')
4488
     * @param string $extraFieldId
4489
     * @param int $daysCoachAccessBeforeBeginning
4490
     * @param int $daysCoachAccessAfterBeginning
4491
     * @param int $sessionVisibility
4492
     * @param array $fieldsToAvoidUpdate
4493
     * @param bool $deleteUsersNotInList
4494
     * @param bool $updateCourseCoaches
4495
     * @param bool $sessionWithCoursesModifier
4496
     * @param bool $addOriginalCourseTeachersAsCourseSessionCoaches
4497
     * @param bool $removeAllTeachersFromCourse
4498
     * @param int $showDescription
4499
     * @param array $teacherBackupList
4500
     * @param array $groupBackup
4501
     * @return array
4502
     */
4503
    public static function importCSV(
4504
        $file,
4505
        $updateSession,
4506
        $defaultUserId = null,
4507
        $logger = null,
4508
        $extraFields = [],
4509
        $extraFieldId = null,
4510
        $daysCoachAccessBeforeBeginning = null,
4511
        $daysCoachAccessAfterBeginning = null,
4512
        $sessionVisibility = 1,
4513
        $fieldsToAvoidUpdate = [],
4514
        $deleteUsersNotInList = false,
4515
        $updateCourseCoaches = false,
4516
        $sessionWithCoursesModifier = false,
4517
        $addOriginalCourseTeachersAsCourseSessionCoaches = true,
4518
        $removeAllTeachersFromCourse = true,
4519
        $showDescription = null,
4520
        &$teacherBackupList = [],
4521
        &$groupBackup = []
4522
    ) {
4523
        $content = file($file);
4524
        $error_message = null;
4525
        $session_counter = 0;
4526
        $defaultUserId = empty($defaultUserId) ? api_get_user_id() : (int) $defaultUserId;
4527
4528
        $eol = PHP_EOL;
4529
        if (PHP_SAPI != 'cli') {
4530
            $eol = '<br />';
4531
        }
4532
4533
        $debug = false;
4534
        if (isset($logger)) {
4535
            $debug = true;
4536
        }
4537
4538
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
4539
        $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
4540
        $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4541
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
4542
        $sessions = [];
4543
        if (!api_strstr($content[0], ';')) {
4544
            $error_message = get_lang('NotCSV');
4545
        } else {
4546
            $tag_names = [];
4547
            foreach ($content as $key => $enreg) {
4548
                $enreg = explode(';', trim($enreg));
4549
                if ($key) {
4550
                    foreach ($tag_names as $tag_key => $tag_name) {
4551
                        if (isset($enreg[$tag_key])) {
4552
                            $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
4553
                        }
4554
                    }
4555
                } else {
4556
                    foreach ($enreg as $tag_name) {
4557
                        $tag_names[] = api_preg_replace('/[^a-zA-Z0-9_\-]/', '', $tag_name);
4558
                    }
4559
                    if (!in_array('SessionName', $tag_names) ||
4560
                        !in_array('DateStart', $tag_names) ||
4561
                        !in_array('DateEnd', $tag_names)
4562
                    ) {
4563
                        $error_message = get_lang('NoNeededData');
4564
                        break;
4565
                    }
4566
                }
4567
            }
4568
4569
            $sessionList = [];
4570
            // Looping the sessions.
4571
            foreach ($sessions as $enreg) {
4572
                $user_counter = 0;
4573
                $course_counter = 0;
4574
4575
                if (isset($extraFields) && !empty($extraFields)) {
4576
                    foreach ($extraFields as $original => $to) {
4577
                        $enreg[$to] = isset($enreg[$original]) ? $enreg[$original] : null;
4578
                    }
4579
                }
4580
4581
                $session_name = $enreg['SessionName'];
4582
                // Default visibility
4583
                $visibilityAfterExpirationPerSession = $sessionVisibility;
4584
4585
                if (isset($enreg['VisibilityAfterExpiration'])) {
4586
                    $visibility = $enreg['VisibilityAfterExpiration'];
4587
                    switch ($visibility) {
4588
                        case 'read_only':
4589
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE_READ_ONLY;
4590
                            break;
4591
                        case 'accessible':
4592
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE;
4593
                            break;
4594
                        case 'not_accessible':
4595
                            $visibilityAfterExpirationPerSession = SESSION_INVISIBLE;
4596
                            break;
4597
                    }
4598
                }
4599
4600
                if (empty($session_name)) {
4601
                    continue;
4602
                }
4603
4604
                $displayAccessStartDate = isset($enreg['DisplayStartDate']) ? $enreg['DisplayStartDate'] : $enreg['DateStart'];
4605
                $displayAccessEndDate = isset($enreg['DisplayEndDate']) ? $enreg['DisplayEndDate'] : $enreg['DateEnd'];
4606
                $coachAccessStartDate = isset($enreg['CoachStartDate']) ? $enreg['CoachStartDate'] : $enreg['DateStart'];
4607
                $coachAccessEndDate = isset($enreg['CoachEndDate']) ? $enreg['CoachEndDate'] : $enreg['DateEnd'];
4608
                // We assume the dates are already in UTC
4609
                $dateStart = explode('/', $enreg['DateStart']);
4610
                $dateEnd = explode('/', $enreg['DateEnd']);
4611
                $dateStart = $dateStart[0].'-'.$dateStart[1].'-'.$dateStart[2].' 00:00:00';
4612
                $dateEnd = $dateEnd[0].'-'.$dateEnd[1].'-'.$dateEnd[2].' 23:59:59';
4613
                $displayAccessStartDate = explode('/', $displayAccessStartDate);
4614
                $displayAccessStartDate = implode('-', $displayAccessStartDate).' 00:00:00';
4615
                $displayAccessEndDate = explode('/', $displayAccessEndDate);
4616
                $displayAccessEndDate = implode('-', $displayAccessEndDate).' 23:59:59';
4617
                $coachAccessStartDate = explode('/', $coachAccessStartDate);
4618
                $coachAccessStartDate = implode('-', $coachAccessStartDate).' 00:00:00';
4619
                $coachAccessEndDate = explode('/', $coachAccessEndDate);
4620
                $coachAccessEndDate = implode('-', $coachAccessEndDate).' 23:59:59';
4621
                $session_category_id = isset($enreg['SessionCategory']) ? $enreg['SessionCategory'] : null;
4622
                $sessionDescription = isset($enreg['SessionDescription']) ? $enreg['SessionDescription'] : null;
4623
                $classes = isset($enreg['Classes']) ? explode('|', $enreg['Classes']) : [];
4624
                $extraParams = [];
4625
                if (!is_null($showDescription)) {
4626
                    $extraParams['show_description'] = intval($showDescription);
4627
                }
4628
4629
                $coachBefore = '';
4630
                $coachAfter = '';
4631
4632
                if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
4633
                    $date = new \DateTime($dateStart);
4634
                    $interval = new DateInterval(
4635
                        'P'.$daysCoachAccessBeforeBeginning.'D'
4636
                    );
4637
                    $date->sub($interval);
4638
                    $coachBefore = $date->format('Y-m-d h:i');
4639
                    $coachAccessStartDate = $coachBefore;
4640
                    $coachBefore = api_get_utc_datetime($coachBefore);
4641
4642
                    //$extraParameters .= " , coach_access_start_date = '$coachBefore'";
4643
                    //$extraParams['coach_access_start_date'] = $coachBefore;
4644
4645
                    $date = new \DateTime($dateEnd);
4646
                    $interval = new DateInterval('P'.$daysCoachAccessAfterBeginning.'D');
4647
                    $date->add($interval);
4648
                    $coachAfter = $date->format('Y-m-d h:i');
4649
                    $coachAccessEndDate = $coachAfter;
4650
                    $coachAfter = api_get_utc_datetime($coachAfter);
4651
                    //$extraParameters .= " , coach_access_end_date = '$coachAfter'";
4652
                    //$extraParams['coach_access_end_date'] = $coachAfter;
4653
                }
4654
4655
                $dateStart = api_get_utc_datetime($dateStart);
4656
                $dateEnd = api_get_utc_datetime($dateEnd);
4657
                $displayAccessStartDate = api_get_utc_datetime($displayAccessStartDate);
4658
                $displayAccessEndDate = api_get_utc_datetime($displayAccessEndDate);
4659
                $coachAccessStartDate = api_get_utc_datetime($coachAccessStartDate);
4660
                $coachAccessEndDate = api_get_utc_datetime($coachAccessEndDate);
4661
4662
                if (!empty($sessionDescription)) {
4663
                    $extraParams['description'] = $sessionDescription;
4664
                    //$extraSessionParameters = " , description = '".Database::escape_string($sessionDescription)."'";
4665
                }
4666
4667
                //$sessionCondition = '';
4668
                if (!empty($session_category_id)) {
4669
                    $extraParams['session_category_id'] = $session_category_id;
4670
                    //$sessionCondition = " , session_category_id = '$session_category_id' ";
4671
                }
4672
4673
                // Searching a general coach.
4674
                if (!empty($enreg['Coach'])) {
4675
                    $coach_id = UserManager::get_user_id_from_username($enreg['Coach']);
4676
                    if ($coach_id === false) {
4677
                        // If the coach-user does not exist - I'm the coach.
4678
                        $coach_id = $defaultUserId;
4679
                    }
4680
                } else {
4681
                    $coach_id = $defaultUserId;
4682
                }
4683
4684
                $users = explode('|', $enreg['Users']);
4685
                $courses = explode('|', $enreg['Courses']);
4686
4687
                $deleteOnlyCourseCoaches = false;
4688
                if (count($courses) == 1) {
4689
                    if ($logger) {
4690
                        $logger->addInfo('Only one course delete old coach list');
4691
                    }
4692
                    $deleteOnlyCourseCoaches = true;
4693
                }
4694
4695
                if (!$updateSession) {
4696
                    // Always create a session.
4697
                    $unique_name = false;
4698
                    $i = 0;
4699
                    // Change session name, verify that session doesn't exist.
4700
                    $suffix = null;
4701
                    while (!$unique_name) {
4702
                        if ($i > 1) {
4703
                            $suffix = ' - '.$i;
4704
                        }
4705
                        $sql = 'SELECT 1 FROM '.$tbl_session.'
4706
                                WHERE name="' . Database::escape_string($session_name).$suffix.'"';
4707
                        $rs = Database::query($sql);
4708
4709
                        if (Database::result($rs, 0, 0)) {
4710
                            $i++;
4711
                        } else {
4712
                            $unique_name = true;
4713
                            $session_name .= $suffix;
4714
                        }
4715
                    }
4716
4717
                    $sessionParams = [
4718
                        'name' => $session_name,
4719
                        'id_coach' => $coach_id,
4720
                        'access_start_date' => $dateStart,
4721
                        'access_end_date' => $dateEnd,
4722
                        'display_start_date' => $displayAccessStartDate,
4723
                        'display_end_date' => $displayAccessEndDate,
4724
                        'coach_access_start_date' => $coachAccessStartDate,
4725
                        'coach_access_end_date' => $coachAccessEndDate,
4726
                        'visibility' => $visibilityAfterExpirationPerSession,
4727
                        'session_admin_id' => $defaultUserId
4728
                    ];
4729
4730
                    if (!empty($extraParams)) {
4731
                        $sessionParams = array_merge($sessionParams, $extraParams);
4732
                    }
4733
                    $session_id = Database::insert($tbl_session, $sessionParams);
4734
4735
                    // Creating the session.
4736
                    /*$sql = "INSERT IGNORE INTO $tbl_session SET
4737
4738
                            $sessionCondition
4739
                            $extraParameters
4740
                            $extraSessionParameters";
4741
                    Database::query($sql);
4742
                    $session_id = Database::insert_id();*/
4743
                    if ($debug) {
4744
                        if ($session_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $session_id of type integer|false is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
4745
                            foreach ($enreg as $key => $value) {
4746
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
4747
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
4748
                                }
4749
                            }
4750
4751
                            $logger->addInfo("Sessions - Session created: #$session_id - $session_name");
0 ignored issues
show
Bug introduced by
The method addInfo() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4751
                            $logger->/** @scrutinizer ignore-call */ 
4752
                                     addInfo("Sessions - Session created: #$session_id - $session_name");

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
4752
                        } else {
4753
                            $logger->addError("Sessions - Session NOT created: $session_name");
4754
                        }
4755
                    }
4756
                    $session_counter++;
4757
                } else {
4758
                    $sessionId = null;
4759
                    if (isset($extraFields) && !empty($extraFields) && !empty($enreg['extra_'.$extraFieldId])) {
4760
                        $sessionId = self::getSessionIdFromOriginalId($enreg['extra_'.$extraFieldId], $extraFieldId);
4761
                        if (empty($sessionId)) {
4762
                            $my_session_result = false;
4763
                        } else {
4764
                            $my_session_result = true;
4765
                        }
4766
                    } else {
4767
                        $my_session_result = self::get_session_by_name($enreg['SessionName']);
4768
                    }
4769
4770
                    if ($my_session_result === false) {
4771
                        $sessionParams = [
4772
                            'name' => $session_name,
4773
                            'id_coach' => $coach_id,
4774
                            'access_start_date' => $dateStart,
4775
                            'access_end_date' => $dateEnd,
4776
                            'display_start_date' => $displayAccessStartDate,
4777
                            'display_end_date' => $displayAccessEndDate,
4778
                            'coach_access_start_date' => $coachAccessStartDate,
4779
                            'coach_access_end_date' => $coachAccessEndDate,
4780
                            'visibility' => $visibilityAfterExpirationPerSession,
4781
                            'session_admin_id' => $defaultUserId
4782
                        ];
4783
4784
                        if (!empty($extraParams)) {
4785
                            $sessionParams = array_merge($sessionParams, $extraParams);
4786
                        }
4787
                        Database::insert($tbl_session, $sessionParams);
4788
4789
                        // We get the last insert id.
4790
                        $my_session_result = self::get_session_by_name($enreg['SessionName']);
4791
                        $session_id = $my_session_result['id'];
4792
4793
                        if ($session_id) {
4794
                            foreach ($enreg as $key => $value) {
4795
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
4796
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
4797
                                }
4798
                            }
4799
                            if ($debug) {
4800
                                $logger->addInfo("Sessions - #$session_id created: $session_name");
4801
                            }
4802
4803
                            // Delete session-user relation only for students
4804
                            $sql = "DELETE FROM $tbl_session_user
4805
                                    WHERE session_id = '$session_id' AND relation_type <> ".SESSION_RELATION_TYPE_RRHH;
4806
                            Database::query($sql);
4807
4808
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
4809
                            Database::query($sql);
4810
4811
                            // Delete session-course-user relationships students and coaches.
4812
                            if ($updateCourseCoaches) {
4813
                                $sql = "DELETE FROM $tbl_session_course_user
4814
                                        WHERE session_id = '$session_id' AND status in ('0', '2')";
4815
                                Database::query($sql);
4816
                            } else {
4817
                                // Delete session-course-user relation ships *only* for students.
4818
                                $sql = "DELETE FROM $tbl_session_course_user
4819
                                        WHERE session_id = '$session_id' AND status <> 2";
4820
                                Database::query($sql);
4821
                            }
4822
                            if ($deleteOnlyCourseCoaches) {
4823
                                $sql = "DELETE FROM $tbl_session_course_user
4824
                                        WHERE session_id = '$session_id' AND status in ('2')";
4825
                                Database::query($sql);
4826
                            }
4827
                        }
4828
                    } else {
4829
                        // Updating the session.
4830
                        $params = [
4831
                            'id_coach' => $coach_id,
4832
                            'access_start_date' => $dateStart,
4833
                            'access_end_date' => $dateEnd,
4834
                            'display_start_date' => $dateStart,
4835
                            'display_end_date' => $dateEnd,
4836
                            'display_start_date' => $displayAccessStartDate,
4837
                            'display_end_date' => $displayAccessEndDate,
4838
                            'coach_access_start_date' => $coachAccessStartDate,
4839
                            'coach_access_end_date' => $coachAccessEndDate,
4840
                            'visibility' => $visibilityAfterExpirationPerSession,
4841
                            'session_category_id' => $session_category_id,
4842
                        ];
4843
4844
                        if (!empty($sessionDescription)) {
4845
                            $params['description'] = $sessionDescription;
4846
                        }
4847
4848
                        if (!empty($fieldsToAvoidUpdate)) {
4849
                            foreach ($fieldsToAvoidUpdate as $field) {
4850
                                unset($params[$field]);
4851
                            }
4852
                        }
4853
4854
                        if (isset($sessionId) && !empty($sessionId)) {
4855
                            $session_id = $sessionId;
4856
                            if (!empty($enreg['SessionName'])) {
4857
                                $sessionName = Database::escape_string($enreg['SessionName']);
4858
                                $sql = "UPDATE $tbl_session SET name = '$sessionName' WHERE id = $session_id";
4859
                                Database::query($sql);
4860
                            }
4861
                        } else {
4862
                            $my_session_result = self::get_session_by_name($session_name);
4863
                            $session_id = $my_session_result['id'];
4864
                        }
4865
4866
                        if ($debug) {
4867
                            $logger->addError("Sessions - Session #$session_id to be updated: '$session_name'");
4868
                        }
4869
4870
                        if ($session_id) {
4871
                            if ($debug) {
4872
                                $logger->addError("Sessions - Session to be updated #$session_id");
4873
                            }
4874
4875
                            $sessionInfo = api_get_session_info($session_id);
4876
                            $params['show_description'] = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : intval($showDescription);
4877
4878
                            if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
4879
                                if (empty($sessionInfo['nb_days_access_before_beginning']) ||
4880
                                    (!empty($sessionInfo['nb_days_access_before_beginning']) &&
4881
                                        $sessionInfo['nb_days_access_before_beginning'] < $daysCoachAccessBeforeBeginning)
4882
                                ) {
4883
                                    $params['coach_access_start_date'] = $coachBefore;
4884
                                }
4885
4886
                                if (empty($sessionInfo['nb_days_access_after_end']) ||
4887
                                    (!empty($sessionInfo['nb_days_access_after_end']) &&
4888
                                        $sessionInfo['nb_days_access_after_end'] < $daysCoachAccessAfterBeginning)
4889
                                ) {
4890
                                    $params['coach_access_end_date'] = $coachAfter;
4891
                                }
4892
                            }
4893
4894
                            Database::update($tbl_session, $params, ['id = ?' => $session_id]);
4895
4896
                            foreach ($enreg as $key => $value) {
4897
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
4898
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
4899
                                }
4900
                            }
4901
4902
                            // Delete session-user relation only for students
4903
                            $sql = "DELETE FROM $tbl_session_user
4904
                                    WHERE session_id = '$session_id' AND relation_type <> ".SESSION_RELATION_TYPE_RRHH;
4905
                            Database::query($sql);
4906
4907
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
4908
                            Database::query($sql);
4909
4910
                            // Delete session-course-user relationships students and coaches.
4911
                            if ($updateCourseCoaches) {
4912
                                $sql = "DELETE FROM $tbl_session_course_user
4913
                                        WHERE session_id = '$session_id' AND status in ('0', '2')";
4914
                                Database::query($sql);
4915
                            } else {
4916
                                // Delete session-course-user relation ships *only* for students.
4917
                                $sql = "DELETE FROM $tbl_session_course_user
4918
                                        WHERE session_id = '$session_id' AND status <> 2";
4919
                                Database::query($sql);
4920
                            }
4921
4922
                            if ($deleteOnlyCourseCoaches) {
4923
                                $sql = "DELETE FROM $tbl_session_course_user
4924
                                        WHERE session_id = '$session_id' AND status in ('2')";
4925
                                Database::query($sql);
4926
                            }
4927
                        } else {
4928
                            if ($debug) {
4929
                                $logger->addError(
4930
                                    "Sessions - Session not found"
4931
                                );
4932
                            }
4933
                        }
4934
                    }
4935
                    $session_counter++;
4936
                }
4937
4938
                $sessionList[] = $session_id;
4939
4940
                // Adding the relationship "Session - User" for students
4941
                $userList = [];
4942
                if (is_array($users)) {
4943
                    foreach ($users as $user) {
4944
                        $user_id = UserManager::get_user_id_from_username($user);
4945
                        if ($user_id !== false) {
4946
                            $userList[] = $user_id;
4947
                            // Insert new users.
4948
                            $sql = "INSERT IGNORE INTO $tbl_session_user SET
4949
                                    user_id = '$user_id',
4950
                                    session_id = '$session_id',
4951
                                    registered_at = '".api_get_utc_datetime()."'";
4952
                            Database::query($sql);
4953
                            if ($debug) {
4954
                                $logger->addInfo("Sessions - Adding User #$user_id ($user) to session #$session_id");
4955
                            }
4956
                            $user_counter++;
4957
                        }
4958
                    }
4959
                }
4960
4961
                if ($deleteUsersNotInList) {
4962
                    // Getting user in DB in order to compare to the new list.
4963
                    $usersListInDatabase = self::get_users_by_session($session_id, 0);
0 ignored issues
show
Bug introduced by
It seems like $session_id can also be of type false; however, parameter $id of SessionManager::get_users_by_session() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

4963
                    $usersListInDatabase = self::get_users_by_session(/** @scrutinizer ignore-type */ $session_id, 0);
Loading history...
4964
4965
                    if (!empty($usersListInDatabase)) {
4966
                        if (empty($userList)) {
4967
                            foreach ($usersListInDatabase as $userInfo) {
4968
                                self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
4969
                            }
4970
                        } else {
4971
                            foreach ($usersListInDatabase as $userInfo) {
4972
                                if (!in_array($userInfo['user_id'], $userList)) {
4973
                                    self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
4974
                                }
4975
                            }
4976
                        }
4977
                    }
4978
                }
4979
4980
                // See BT#6449
4981
                $onlyAddFirstCoachOrTeacher = false;
4982
                if ($sessionWithCoursesModifier) {
4983
                    if (count($courses) >= 2) {
4984
                        // Only first teacher in course session;
4985
                        $onlyAddFirstCoachOrTeacher = true;
4986
4987
                        // Remove all teachers from course.
4988
                        $removeAllTeachersFromCourse = false;
4989
                    }
4990
                }
4991
4992
                foreach ($courses as $course) {
4993
                    $courseArray = bracketsToArray($course);
4994
                    $course_code = $courseArray[0];
4995
4996
                    if (CourseManager::course_exists($course_code)) {
4997
                        $courseInfo = api_get_course_info($course_code);
4998
                        $courseId = $courseInfo['real_id'];
4999
5000
                        // Adding the course to a session.
5001
                        $sql = "INSERT IGNORE INTO $tbl_session_course
5002
                                SET c_id = '$courseId', session_id='$session_id'";
5003
                        Database::query($sql);
5004
5005
                        self::installCourse($session_id, $courseInfo['real_id']);
0 ignored issues
show
Bug introduced by
It seems like $session_id can also be of type false; however, parameter $sessionId of SessionManager::installCourse() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5005
                        self::installCourse(/** @scrutinizer ignore-type */ $session_id, $courseInfo['real_id']);
Loading history...
5006
5007
                        if ($debug) {
5008
                            $logger->addInfo("Sessions - Adding course '$course_code' to session #$session_id");
5009
                        }
5010
5011
                        $course_counter++;
5012
                        $course_coaches = isset($courseArray[1]) ? $courseArray[1] : null;
5013
                        $course_users = isset($courseArray[2]) ? $courseArray[2] : null;
5014
                        $course_users = explode(',', $course_users);
5015
                        $course_coaches = explode(',', $course_coaches);
5016
5017
                        // Checking if the flag is set TeachersWillBeAddedAsCoachInAllCourseSessions (course_edit.php)
5018
                        $addTeachersToSession = true;
5019
5020
                        if (array_key_exists('add_teachers_to_sessions_courses', $courseInfo)) {
5021
                            $addTeachersToSession = $courseInfo['add_teachers_to_sessions_courses'];
5022
                        }
5023
5024
                        // If any user provided for a course, use the users array.
5025
                        if (empty($course_users)) {
5026
                            if (!empty($userList)) {
5027
                                self::subscribe_users_to_session_course(
5028
                                    $userList,
5029
                                    $session_id,
0 ignored issues
show
Bug introduced by
It seems like $session_id can also be of type false; however, parameter $session_id of SessionManager::subscrib...ers_to_session_course() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5029
                                    /** @scrutinizer ignore-type */ $session_id,
Loading history...
5030
                                    $course_code
5031
                                );
5032
                                if ($debug) {
5033
                                    $msg = "Sessions - Adding student list ".implode(', #', $userList)." to course: '$course_code' and session #$session_id";
5034
                                    $logger->addInfo($msg);
5035
                                }
5036
                            }
5037
                        }
5038
5039
                        // Adding coaches to session course user.
5040
                        if (!empty($course_coaches)) {
5041
                            $savedCoaches = [];
5042
                            // only edit if add_teachers_to_sessions_courses is set.
5043
                            if ($addTeachersToSession) {
5044
                                if ($addOriginalCourseTeachersAsCourseSessionCoaches) {
5045
                                    // Adding course teachers as course session teachers.
5046
                                    $alreadyAddedTeachers = CourseManager::get_teacher_list_from_course_code(
5047
                                        $course_code
5048
                                    );
5049
5050
                                    if (!empty($alreadyAddedTeachers)) {
5051
                                        $teachersToAdd = [];
5052
                                        foreach ($alreadyAddedTeachers as $user) {
5053
                                            $teachersToAdd[] = $user['username'];
5054
                                        }
5055
                                        $course_coaches = array_merge(
5056
                                            $course_coaches,
5057
                                            $teachersToAdd
5058
                                        );
5059
                                    }
5060
                                }
5061
5062
                                foreach ($course_coaches as $course_coach) {
5063
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
5064
                                    if ($coach_id !== false) {
5065
                                        // Just insert new coaches
5066
                                        self::updateCoaches(
5067
                                            $session_id,
0 ignored issues
show
Bug introduced by
It seems like $session_id can also be of type false; however, parameter $sessionId of SessionManager::updateCoaches() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5067
                                            /** @scrutinizer ignore-type */ $session_id,
Loading history...
5068
                                            $courseId,
5069
                                            [$coach_id],
5070
                                            false
5071
                                        );
5072
5073
                                        if ($debug) {
5074
                                            $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
5075
                                        }
5076
                                        $savedCoaches[] = $coach_id;
5077
                                    } else {
5078
                                        $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
5079
                                    }
5080
                                }
5081
                            }
5082
5083
                            // Custom courses/session coaches
5084
                            $teacherToAdd = null;
5085
                            // Only one coach is added.
5086
                            if ($onlyAddFirstCoachOrTeacher == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
5087
                                if ($debug) {
5088
                                    $logger->addInfo("onlyAddFirstCoachOrTeacher : true");
5089
                                }
5090
5091
                                foreach ($course_coaches as $course_coach) {
5092
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
5093
                                    if ($coach_id !== false) {
5094
                                        $teacherToAdd = $coach_id;
5095
                                        break;
5096
                                    }
5097
                                }
5098
5099
                                // Un subscribe everyone that's not in the list.
5100
                                $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
5101
                                if (!empty($teacherList)) {
5102
                                    foreach ($teacherList as $teacher) {
5103
                                        if ($teacherToAdd != $teacher['user_id']) {
5104
                                            $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
5105
                                                    WHERE
5106
                                                        user_id = ".$teacher['user_id']." AND
5107
                                                        c_id = '".$courseId."'
5108
                                                    ";
5109
5110
                                            $result = Database::query($sql);
5111
                                            $rows = Database::num_rows($result);
5112
                                            if ($rows > 0) {
5113
                                                $userCourseData = Database::fetch_array($result, 'ASSOC');
5114
                                                if (!empty($userCourseData)) {
5115
                                                    $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
5116
                                                }
5117
                                            }
5118
5119
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
5120
                                                    WHERE
5121
                                                        user_id = ".$teacher['user_id']." AND
5122
                                                        c_id = '".$courseInfo['real_id']."'
5123
                                                    ";
5124
5125
                                            $result = Database::query($sql);
5126
                                            while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5127
                                                $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5128
                                            }
5129
5130
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
5131
                                                    WHERE
5132
                                                        user_id = ".$teacher['user_id']." AND
5133
                                                        c_id = '".$courseInfo['real_id']."'
5134
                                                    ";
5135
5136
                                            $result = Database::query($sql);
5137
                                            while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5138
                                                $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5139
                                            }
5140
5141
                                            CourseManager::unsubscribe_user(
5142
                                                $teacher['user_id'],
5143
                                                $course_code
5144
                                            );
5145
5146
                                            if ($debug) {
5147
                                                $logger->addInfo("Delete user #".$teacher['user_id']." from base course: $course_code");
5148
                                            }
5149
                                        }
5150
                                    }
5151
                                }
5152
5153
                                if (!empty($teacherToAdd)) {
5154
                                    self::updateCoaches(
5155
                                        $session_id,
5156
                                        $courseId,
5157
                                        [$teacherToAdd],
5158
                                        true
5159
                                    );
5160
5161
                                    if ($debug) {
5162
                                        $logger->addInfo("Add coach #$teacherToAdd to course $courseId and session $session_id");
5163
                                    }
5164
5165
                                    $userCourseCategory = '';
5166
                                    if (isset($teacherBackupList[$teacherToAdd]) &&
5167
                                        isset($teacherBackupList[$teacherToAdd][$course_code])
5168
                                    ) {
5169
                                        $courseUserData = $teacherBackupList[$teacherToAdd][$course_code];
5170
                                        $userCourseCategory = $courseUserData['user_course_cat'];
5171
                                    }
5172
5173
                                    CourseManager::subscribe_user(
5174
                                        $teacherToAdd,
5175
                                        $course_code,
5176
                                        COURSEMANAGER,
5177
                                        0,
5178
                                        $userCourseCategory
0 ignored issues
show
Bug introduced by
It seems like $userCourseCategory can also be of type string; however, parameter $userCourseCategoryId of CourseManager::subscribe_user() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5178
                                        /** @scrutinizer ignore-type */ $userCourseCategory
Loading history...
5179
                                    );
5180
5181
                                    if ($debug) {
5182
                                        $logger->addInfo("Subscribe user #$teacherToAdd as teacher in course $course_code with user userCourseCategory $userCourseCategory");
5183
                                    }
5184
5185
                                    if (isset($groupBackup['user'][$teacherToAdd]) &&
5186
                                        isset($groupBackup['user'][$teacherToAdd][$course_code]) &&
5187
                                        !empty($groupBackup['user'][$teacherToAdd][$course_code])
5188
                                    ) {
5189
                                        foreach ($groupBackup['user'][$teacherToAdd][$course_code] as $data) {
5190
                                            $groupInfo = GroupManager::get_group_properties($data['group_id']);
5191
                                            GroupManager::subscribe_users(
5192
                                                $teacherToAdd,
5193
                                                $groupInfo,
5194
                                                $data['c_id']
5195
                                            );
5196
                                        }
5197
                                    }
5198
5199
                                    if (isset($groupBackup['tutor'][$teacherToAdd]) &&
5200
                                        isset($groupBackup['tutor'][$teacherToAdd][$course_code]) &&
5201
                                        !empty($groupBackup['tutor'][$teacherToAdd][$course_code])
5202
                                    ) {
5203
                                        foreach ($groupBackup['tutor'][$teacherToAdd][$course_code] as $data) {
5204
                                            $groupInfo = GroupManager::get_group_properties($data['group_id']);
5205
                                            GroupManager::subscribe_tutors(
5206
                                                $teacherToAdd,
5207
                                                $groupInfo,
5208
                                                $data['c_id']
5209
                                            );
5210
                                        }
5211
                                    }
5212
                                }
5213
                            }
5214
5215
                            // See BT#6449#note-195
5216
                            // All coaches are added.
5217
                            if ($removeAllTeachersFromCourse) {
5218
                                if ($debug) {
5219
                                    $logger->addInfo("removeAllTeachersFromCourse true");
5220
                                }
5221
                                $teacherToAdd = null;
5222
                                foreach ($course_coaches as $course_coach) {
5223
                                    $coach_id = UserManager::get_user_id_from_username(
5224
                                        $course_coach
5225
                                    );
5226
                                    if ($coach_id !== false) {
5227
                                        $teacherToAdd[] = $coach_id;
5228
                                    }
5229
                                }
5230
5231
                                if (!empty($teacherToAdd)) {
5232
                                    // Deleting all course teachers and adding the only coach as teacher.
5233
                                    $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
5234
5235
                                    if (!empty($teacherList)) {
5236
                                        foreach ($teacherList as $teacher) {
5237
                                            if (!in_array($teacher['user_id'], $teacherToAdd)) {
5238
                                                $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
5239
                                                        WHERE
5240
                                                            user_id = ".$teacher['user_id']." AND
5241
                                                            c_id = '".$courseId."'
5242
                                                        ";
5243
5244
                                                $result = Database::query($sql);
5245
                                                $rows = Database::num_rows($result);
5246
                                                if ($rows > 0) {
5247
                                                    $userCourseData = Database::fetch_array($result, 'ASSOC');
5248
                                                    if (!empty($userCourseData)) {
5249
                                                        $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
5250
                                                    }
5251
                                                }
5252
5253
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
5254
                                                        WHERE
5255
                                                            user_id = ".$teacher['user_id']." AND
5256
                                                            c_id = '".$courseInfo['real_id']."'
5257
                                                        ";
5258
5259
                                                $result = Database::query($sql);
5260
                                                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5261
                                                    $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5262
                                                }
5263
5264
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
5265
                                                        WHERE
5266
                                                            user_id = ".$teacher['user_id']." AND
5267
                                                            c_id = '".$courseInfo['real_id']."'
5268
                                                        ";
5269
5270
                                                $result = Database::query($sql);
5271
                                                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5272
                                                    $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5273
                                                }
5274
5275
                                                CourseManager::unsubscribe_user(
5276
                                                    $teacher['user_id'],
5277
                                                    $course_code
5278
                                                );
5279
5280
                                                if ($debug) {
5281
                                                    $logger->addInfo("Delete user #".$teacher['user_id']." from base course: $course_code");
5282
                                                }
5283
                                            }
5284
                                        }
5285
                                    }
5286
5287
                                    foreach ($teacherToAdd as $teacherId) {
5288
                                        $userCourseCategory = '';
5289
                                        if (isset($teacherBackupList[$teacherId]) &&
5290
                                            isset($teacherBackupList[$teacherId][$course_code])
5291
                                        ) {
5292
                                            $courseUserData = $teacherBackupList[$teacherId][$course_code];
5293
                                            $userCourseCategory = $courseUserData['user_course_cat'];
5294
                                        }
5295
5296
                                        CourseManager::subscribe_user(
5297
                                            $teacherId,
5298
                                            $course_code,
5299
                                            COURSEMANAGER,
5300
                                            0,
5301
                                            $userCourseCategory
5302
                                        );
5303
5304
                                        if ($debug) {
5305
                                            $logger->addInfo("Add user as teacher #".$teacherId." in base course: $course_code with userCourseCategory: $userCourseCategory");
5306
                                        }
5307
5308
                                        if (isset($groupBackup['user'][$teacherId]) &&
5309
                                            isset($groupBackup['user'][$teacherId][$course_code]) &&
5310
                                            !empty($groupBackup['user'][$teacherId][$course_code])
5311
                                        ) {
5312
                                            foreach ($groupBackup['user'][$teacherId][$course_code] as $data) {
5313
                                                $groupInfo = GroupManager::get_group_properties($data['group_id']);
5314
                                                GroupManager::subscribe_users(
5315
                                                    $teacherId,
5316
                                                    $groupInfo,
5317
                                                    $data['c_id']
5318
                                                );
5319
                                            }
5320
                                        }
5321
5322
                                        if (isset($groupBackup['tutor'][$teacherId]) &&
5323
                                            isset($groupBackup['tutor'][$teacherId][$course_code]) &&
5324
                                            !empty($groupBackup['tutor'][$teacherId][$course_code])
5325
                                        ) {
5326
                                            foreach ($groupBackup['tutor'][$teacherId][$course_code] as $data) {
5327
                                                $groupInfo = GroupManager::get_group_properties($data['group_id']);
5328
                                                GroupManager::subscribe_tutors(
5329
                                                    $teacherId,
5330
                                                    $groupInfo,
5331
                                                    $data['c_id']
5332
                                                );
5333
                                            }
5334
                                        }
5335
                                    }
5336
                                }
5337
                            }
5338
5339
                            // Continue default behaviour.
5340
                            if ($onlyAddFirstCoachOrTeacher == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
5341
                                // Checking one more time see BT#6449#note-149
5342
                                $coaches = self::getCoachesByCourseSession($session_id, $courseId);
0 ignored issues
show
Bug introduced by
It seems like $session_id can also be of type false; however, parameter $sessionId of SessionManager::getCoachesByCourseSession() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5342
                                $coaches = self::getCoachesByCourseSession(/** @scrutinizer ignore-type */ $session_id, $courseId);
Loading history...
5343
                                // Update coaches if only there's 1 course see BT#6449#note-189
5344
                                if (empty($coaches) || count($courses) == 1) {
5345
                                    foreach ($course_coaches as $course_coach) {
5346
                                        $course_coach = trim($course_coach);
5347
                                        $coach_id = UserManager::get_user_id_from_username($course_coach);
5348
                                        if ($coach_id !== false) {
5349
                                            // Just insert new coaches
5350
                                            self::updateCoaches(
5351
                                                $session_id,
5352
                                                $courseId,
5353
                                                [$coach_id],
5354
                                                false
5355
                                            );
5356
5357
                                            if ($debug) {
5358
                                                $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
5359
                                            }
5360
                                            $savedCoaches[] = $coach_id;
5361
                                        } else {
5362
                                            $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
5363
                                        }
5364
                                    }
5365
                                }
5366
                            }
5367
                        }
5368
5369
                        // Adding Students, updating relationship "Session - Course - User".
5370
                        $course_users = array_filter($course_users);
5371
5372
                        if (!empty($course_users)) {
5373
                            foreach ($course_users as $user) {
5374
                                $user_id = UserManager::get_user_id_from_username($user);
5375
5376
                                if ($user_id !== false) {
5377
                                    self::subscribe_users_to_session_course(
5378
                                        [$user_id],
5379
                                        $session_id,
5380
                                        $course_code
5381
                                    );
5382
                                    if ($debug) {
5383
                                        $logger->addInfo("Sessions - Adding student: user #$user_id ($user) to course: '$course_code' and session #$session_id");
5384
                                    }
5385
                                } else {
5386
                                    $error_message .= get_lang('UserDoesNotExist').': '.$user.$eol;
5387
                                }
5388
                            }
5389
                        }
5390
5391
                        $inserted_in_course[$course_code] = $courseInfo['title'];
5392
                    }
5393
                }
5394
                $access_url_id = api_get_current_access_url_id();
5395
                UrlManager::add_session_to_url($session_id, $access_url_id);
0 ignored issues
show
Bug introduced by
It seems like $session_id can also be of type false; however, parameter $session_id of UrlManager::add_session_to_url() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5395
                UrlManager::add_session_to_url(/** @scrutinizer ignore-type */ $session_id, $access_url_id);
Loading history...
5396
                $sql = "UPDATE $tbl_session SET nbr_users = '$user_counter', nbr_courses = '$course_counter' 
5397
                        WHERE id = '$session_id'";
5398
                Database::query($sql);
5399
5400
                self::addClassesByName($session_id, $classes, false);
0 ignored issues
show
Bug introduced by
It seems like $session_id can also be of type false; however, parameter $sessionId of SessionManager::addClassesByName() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5400
                self::addClassesByName(/** @scrutinizer ignore-type */ $session_id, $classes, false);
Loading history...
5401
            }
5402
        }
5403
5404
        return [
5405
            'error_message' => $error_message,
5406
            'session_counter' => $session_counter,
5407
            'session_list' => $sessionList,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $sessionList does not seem to be defined for all execution paths leading up to this point.
Loading history...
5408
        ];
5409
    }
5410
5411
    /**
5412
     * Add classes (by their names) to a session
5413
     * @param int $sessionId
5414
     * @param array $classesNames
5415
     * @param bool $deleteClassSessions Optional. Empty the session list for the usergroup (class)
5416
     */
5417
    private static function addClassesByName($sessionId, $classesNames, $deleteClassSessions = true)
5418
    {
5419
        if (!$classesNames) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $classesNames of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
5420
            return;
5421
        }
5422
5423
        $usergroup = new UserGroup();
5424
5425
        foreach ($classesNames as $className) {
5426
            if (empty($className)) {
5427
                continue;
5428
            }
5429
5430
            $usergroup->subscribe_sessions_to_usergroup(
5431
                $usergroup->get_id_by_name($className),
5432
                [$sessionId],
5433
                $deleteClassSessions
5434
            );
5435
        }
5436
    }
5437
5438
    /**
5439
     * @param int $sessionId
5440
     * @param int $courseId
5441
     * @return array
5442
     */
5443
    public static function getCoachesByCourseSession($sessionId, $courseId)
5444
    {
5445
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5446
        $sessionId = intval($sessionId);
5447
        $courseId = intval($courseId);
5448
5449
        $sql = "SELECT user_id FROM $table
5450
                WHERE
5451
                    session_id = '$sessionId' AND
5452
                    c_id = '$courseId' AND
5453
                    status = 2";
5454
        $result = Database::query($sql);
5455
5456
        $coaches = [];
5457
        if (Database::num_rows($result) > 0) {
5458
            while ($row = Database::fetch_array($result)) {
5459
                $coaches[] = $row['user_id'];
5460
            }
5461
        }
5462
5463
        return $coaches;
5464
    }
5465
5466
    /**
5467
     * @param int $sessionId
5468
     * @param int $courseId
5469
     * @return string
5470
     */
5471
    public static function getCoachesByCourseSessionToString(
5472
        $sessionId,
5473
        $courseId
5474
    ) {
5475
        $coaches = self::getCoachesByCourseSession($sessionId, $courseId);
5476
        $list = [];
5477
        if (!empty($coaches)) {
5478
            foreach ($coaches as $coachId) {
5479
                $userInfo = api_get_user_info($coachId);
5480
                if ($userInfo) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $userInfo of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
5481
                    $list[] = $userInfo['complete_name'];
5482
                }
5483
            }
5484
        }
5485
5486
        return array_to_string($list, CourseManager::USER_SEPARATOR);
5487
    }
5488
5489
    /**
5490
     * Get all coaches added in the session - course relationship
5491
     * @param int $sessionId
5492
     * @return array
5493
     */
5494
    public static function getCoachesBySession($sessionId)
5495
    {
5496
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5497
        $sessionId = intval($sessionId);
5498
5499
        $sql = "SELECT DISTINCT user_id
5500
                FROM $table
5501
                WHERE session_id = '$sessionId' AND status = 2";
5502
        $result = Database::query($sql);
5503
5504
        $coaches = [];
5505
        if (Database::num_rows($result) > 0) {
5506
            while ($row = Database::fetch_array($result)) {
5507
                $coaches[] = $row['user_id'];
5508
            }
5509
        }
5510
5511
        return $coaches;
5512
    }
5513
5514
    /**
5515
     * @param int $userId
5516
     * @return array
5517
     */
5518
    public static function getAllCoursesFromAllSessionFromDrh($userId)
5519
    {
5520
        $sessions = self::get_sessions_followed_by_drh($userId);
5521
        $coursesFromSession = [];
5522
        if (!empty($sessions)) {
5523
            foreach ($sessions as $session) {
5524
                $courseList = self::get_course_list_by_session_id($session['id']);
5525
                foreach ($courseList as $course) {
5526
                    $coursesFromSession[] = $course['code'];
5527
                }
5528
            }
5529
        }
5530
        return $coursesFromSession;
5531
    }
5532
5533
    /**
5534
     * getAllCoursesFromAllSessions
5535
     *
5536
     * @return array
5537
     */
5538
    public static function getAllCoursesFromAllSessions()
5539
    {
5540
        $sessions = self::get_sessions_list();
5541
        $coursesFromSession = [];
5542
        if (!empty($sessions)) {
5543
            foreach ($sessions as $session) {
5544
                $courseList = self::get_course_list_by_session_id($session['id']);
5545
                foreach ($courseList as $course) {
5546
                    $coursesFromSession[$course['code'].':'.$session['id']] = $course['visual_code'].' - '.$course['title'].' ('.$session['name'].')';
5547
                }
5548
            }
5549
        }
5550
        return $coursesFromSession;
5551
    }
5552
5553
    /**
5554
     * @param string $status
5555
     * @param int $userId
5556
     * @param bool $getCount
5557
     * @param int  $from
5558
     * @param int  $numberItems
5559
     * @param int $column
5560
     * @param string $direction
5561
     * @param string $keyword
5562
     * @param string $active
5563
     * @param string $lastConnectionDate
5564
     * @param array $sessionIdList
5565
     * @param array $studentIdList
5566
     * @param int $filterByStatus
5567
     * @return array|int
5568
     */
5569
    public static function getAllUsersFromCoursesFromAllSessionFromStatus(
5570
        $status,
5571
        $userId,
5572
        $getCount = false,
5573
        $from = null,
5574
        $numberItems = null,
5575
        $column = 1,
5576
        $direction = 'asc',
5577
        $keyword = null,
5578
        $active = null,
5579
        $lastConnectionDate = null,
5580
        $sessionIdList = [],
5581
        $studentIdList = [],
5582
        $filterByStatus = null
5583
    ) {
5584
        $filterByStatus = intval($filterByStatus);
5585
5586
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
5587
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
5588
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
5589
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5590
        $tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
5591
        $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
5592
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5593
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
5594
5595
        $direction = in_array(strtolower($direction), ['asc', 'desc']) ? $direction : 'asc';
5596
        $column = Database::escape_string($column);
5597
        $userId = intval($userId);
5598
5599
        $limitCondition = '';
5600
        if (isset($from) && isset($numberItems)) {
5601
            $from = intval($from);
5602
            $numberItems = intval($numberItems);
5603
            $limitCondition = "LIMIT $from, $numberItems";
5604
        }
5605
5606
        $urlId = api_get_current_access_url_id();
5607
5608
        $sessionConditions = '';
5609
        $courseConditions = '';
5610
        $userConditions = '';
5611
5612
        if (isset($active)) {
5613
            $active = intval($active);
5614
            $userConditions .= " AND active = $active";
5615
        }
5616
5617
        $courseList = CourseManager::get_courses_followed_by_drh($userId, DRH);
5618
        if (!empty($courseList)) {
5619
            $courseIdList = array_column($courseList, 'id');
5620
            $courseConditions = ' AND c.id IN ("'.implode('","', $courseIdList).'")';
5621
        }
5622
5623
        $userConditionsFromDrh = '';
5624
5625
        // Classic DRH
5626
        if (empty($studentIdList)) {
5627
            $studentListSql = UserManager::get_users_followed_by_drh(
5628
                $userId,
5629
                $filterByStatus,
5630
                true,
5631
                false
5632
            );
5633
            if (!empty($studentListSql)) {
5634
                $studentIdList = array_keys($studentListSql);
5635
                $studentListSql = "'".implode("','", $studentIdList)."'";
5636
            }
5637
        } else {
5638
            $studentIdList = array_map('intval', $studentIdList);
5639
            $studentListSql = "'".implode("','", $studentIdList)."'";
5640
        }
5641
        if (!empty($studentListSql)) {
5642
            $userConditionsFromDrh = " AND u.user_id IN (".$studentListSql.") ";
0 ignored issues
show
Bug introduced by
Are you sure $studentListSql of type string|array can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5642
            $userConditionsFromDrh = " AND u.user_id IN ("./** @scrutinizer ignore-type */ $studentListSql.") ";
Loading history...
5643
        }
5644
5645
        switch ($status) {
5646
            case 'drh':
5647
                break;
5648
            case 'drh_all':
5649
                // Show all by DRH
5650
                if (empty($sessionIdList)) {
5651
                    $sessionsListSql = self::get_sessions_followed_by_drh(
5652
                        $userId,
5653
                        null,
5654
                        null,
5655
                        false,
5656
                        true,
5657
                        true
5658
                    );
5659
                } else {
5660
                    $sessionIdList = array_map('intval', $sessionIdList);
5661
                    $sessionsListSql = "'".implode("','", $sessionIdList)."'";
5662
                }
5663
                if (!empty($sessionsListSql)) {
5664
                    $sessionConditions = " AND s.id IN (".$sessionsListSql.") ";
0 ignored issues
show
Bug introduced by
Are you sure $sessionsListSql of type string|array can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5664
                    $sessionConditions = " AND s.id IN ("./** @scrutinizer ignore-type */ $sessionsListSql.") ";
Loading history...
5665
                }
5666
                break;
5667
            case 'session_admin':
5668
                $sessionConditions = " AND s.id_coach = $userId ";
5669
                $userConditionsFromDrh = '';
5670
                break;
5671
            case 'admin':
5672
                break;
5673
            case 'teacher':
5674
                $sessionConditions = " AND s.id_coach = $userId ";
5675
                $userConditionsFromDrh = '';
5676
                break;
5677
        }
5678
5679
        $select = "SELECT DISTINCT u.* ";
5680
        $masterSelect = "SELECT DISTINCT * FROM ";
5681
5682
        if ($getCount) {
5683
            $select = "SELECT DISTINCT u.user_id ";
5684
            $masterSelect = "SELECT COUNT(DISTINCT(user_id)) as count FROM ";
5685
        }
5686
5687
        if (!empty($filterByStatus)) {
5688
            $userConditions .= " AND u.status = ".$filterByStatus;
5689
        }
5690
5691
        if (!empty($lastConnectionDate)) {
5692
            $lastConnectionDate = Database::escape_string($lastConnectionDate);
5693
            $userConditions .= " AND u.last_login <= '$lastConnectionDate' ";
5694
        }
5695
5696
        if (!empty($keyword)) {
5697
            $keyword = Database::escape_string($keyword);
5698
            $userConditions .= " AND (
5699
                u.username LIKE '%$keyword%' OR
5700
                u.firstname LIKE '%$keyword%' OR
5701
                u.lastname LIKE '%$keyword%' OR
5702
                u.official_code LIKE '%$keyword%' OR
5703
                u.email LIKE '%$keyword%'
5704
            )";
5705
        }
5706
5707
        $where = " WHERE
5708
                   access_url_id = $urlId
5709
                   $userConditions
5710
        ";
5711
5712
        $userUnion = '';
5713
        if (!empty($userConditionsFromDrh)) {
5714
            $userUnion = "
5715
            UNION (
5716
                $select                    
5717
                FROM $tbl_user u
5718
                INNER JOIN $tbl_user_rel_access_url url ON (url.user_id = u.id)
5719
                $where
5720
                $userConditionsFromDrh
5721
            )";
5722
        }
5723
5724
        $sql = "$masterSelect (
5725
                ($select
5726
                FROM $tbl_session s
5727
                    INNER JOIN $tbl_session_rel_course_rel_user su ON (s.id = su.session_id)
5728
                    INNER JOIN $tbl_user u ON (u.user_id = su.user_id)
5729
                    INNER JOIN $tbl_session_rel_access_url url ON (url.session_id = s.id)
5730
                    $where
5731
                    $sessionConditions
5732
                    $userConditionsFromDrh
5733
                ) UNION (
5734
                    $select
5735
                    FROM $tbl_course c
5736
                    INNER JOIN $tbl_course_user cu ON (cu.c_id = c.id)
5737
                    INNER JOIN $tbl_user u ON (u.user_id = cu.user_id)
5738
                    INNER JOIN $tbl_course_rel_access_url url ON (url.c_id = c.id)
5739
                    $where
5740
                    $courseConditions
5741
                    $userConditionsFromDrh
5742
                ) $userUnion
5743
                ) as t1
5744
                ";
5745
5746
        if ($getCount) {
5747
            $result = Database::query($sql);
5748
5749
            $count = 0;
5750
            if (Database::num_rows($result)) {
5751
                $rows = Database::fetch_array($result);
5752
                $count = $rows['count'];
5753
            }
5754
            return $count;
5755
        }
5756
5757
        if (!empty($column) && !empty($direction)) {
5758
            $column = str_replace('u.', '', $column);
5759
            $sql .= " ORDER BY $column $direction ";
5760
        }
5761
        $sql .= $limitCondition;
5762
        $result = Database::query($sql);
5763
        $result = Database::store_result($result);
5764
5765
        return $result;
5766
    }
5767
5768
    /**
5769
     * @param int $sessionId
5770
     * @param int $courseId
5771
     * @param array $coachList
5772
     * @param bool $deleteCoachesNotInList
5773
     */
5774
    public static function updateCoaches(
5775
        $sessionId,
5776
        $courseId,
5777
        $coachList,
5778
        $deleteCoachesNotInList = false
5779
    ) {
5780
        $currentCoaches = self::getCoachesByCourseSession($sessionId, $courseId);
5781
5782
        if (!empty($coachList)) {
5783
            foreach ($coachList as $userId) {
5784
                self::set_coach_to_course_session($userId, $sessionId, $courseId);
5785
            }
5786
        }
5787
5788
        if ($deleteCoachesNotInList) {
5789
            if (!empty($coachList)) {
5790
                $coachesToDelete = array_diff($currentCoaches, $coachList);
5791
            } else {
5792
                $coachesToDelete = $currentCoaches;
5793
            }
5794
5795
            if (!empty($coachesToDelete)) {
5796
                foreach ($coachesToDelete as $userId) {
5797
                    self::set_coach_to_course_session(
5798
                        $userId,
5799
                        $sessionId,
5800
                        $courseId,
5801
                        true
5802
                    );
5803
                }
5804
            }
5805
        }
5806
    }
5807
5808
    /**
5809
     * @param array $sessions
5810
     * @param array $sessionsDestination
5811
     * @return array
5812
     */
5813
    public static function copyStudentsFromSession($sessions, $sessionsDestination)
5814
    {
5815
        $messages = [];
5816
        if (!empty($sessions)) {
5817
            foreach ($sessions as $sessionId) {
5818
                $sessionInfo = self::fetch($sessionId);
5819
                $userList = self::get_users_by_session($sessionId, 0);
5820
                if (!empty($userList)) {
5821
                    $newUserList = [];
5822
                    $userToString = null;
5823
                    foreach ($userList as $userInfo) {
5824
                        $newUserList[] = $userInfo['user_id'];
5825
                        $userToString .= $userInfo['firstname'].' '.$userInfo['lastname'].'<br />';
5826
                    }
5827
5828
                    if (!empty($sessionsDestination)) {
5829
                        foreach ($sessionsDestination as $sessionDestinationId) {
5830
                            $sessionDestinationInfo = self::fetch($sessionDestinationId);
5831
                            $messages[] = Display::return_message(
5832
                                sprintf(
5833
                                    get_lang(
5834
                                        'AddingStudentsFromSessionXToSessionY'
5835
                                    ),
5836
                                    $sessionInfo['name'],
5837
                                    $sessionDestinationInfo['name']
5838
                                ),
5839
                                'info',
5840
                                false
5841
                            );
5842
                            if ($sessionId == $sessionDestinationId) {
5843
                                $messages[] = Display::return_message(
5844
                                    sprintf(
5845
                                        get_lang('SessionXSkipped'),
5846
                                        $sessionDestinationId
5847
                                    ),
5848
                                    'warning',
5849
                                    false
5850
                                );
5851
                                continue;
5852
                            }
5853
                            $messages[] = Display::return_message(get_lang('StudentList').'<br />'.$userToString, 'info', false);
5854
                            self::subscribe_users_to_session(
5855
                                $sessionDestinationId,
5856
                                $newUserList,
5857
                                SESSION_VISIBLE_READ_ONLY,
5858
                                false
5859
                            );
5860
                        }
5861
                    } else {
5862
                        $messages[] = Display::return_message(get_lang('NoDestinationSessionProvided'), 'warning');
5863
                    }
5864
                } else {
5865
                    $messages[] = Display::return_message(
5866
                        get_lang('NoStudentsFoundForSession').' #'.$sessionInfo['name'],
5867
                        'warning'
5868
                    );
5869
                }
5870
            }
5871
        } else {
5872
            $messages[] = Display::return_message(get_lang('NoData'), 'warning');
5873
        }
5874
        return $messages;
5875
    }
5876
5877
    /**
5878
     * Assign coaches of a session(s) as teachers to a given course (or courses)
5879
     * @param array A list of session IDs
5880
     * @param array A list of course IDs
5881
     * @return string
5882
     */
5883
    public static function copyCoachesFromSessionToCourse($sessions, $courses)
5884
    {
5885
        $coachesPerSession = [];
5886
        foreach ($sessions as $sessionId) {
5887
            $coaches = self::getCoachesBySession($sessionId);
5888
            $coachesPerSession[$sessionId] = $coaches;
5889
        }
5890
5891
        $result = [];
5892
5893
        if (!empty($courses)) {
5894
            foreach ($courses as $courseId) {
5895
                $courseInfo = api_get_course_info_by_id($courseId);
5896
                foreach ($coachesPerSession as $sessionId => $coachList) {
5897
                    CourseManager::updateTeachers(
5898
                        $courseInfo,
5899
                        $coachList,
5900
                        false,
5901
                        false,
5902
                        false
5903
                    );
5904
                    $result[$courseInfo['code']][$sessionId] = $coachList;
5905
                }
5906
            }
5907
        }
5908
        $sessionUrl = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session=';
5909
        $htmlResult = null;
5910
5911
        if (!empty($result)) {
5912
            foreach ($result as $courseCode => $data) {
5913
                $url = api_get_course_url($courseCode);
5914
                $htmlResult .= sprintf(
5915
                    get_lang('CoachesSubscribedAsATeacherInCourseX'),
5916
                    Display::url($courseCode, $url, ['target' => '_blank'])
5917
                );
5918
                foreach ($data as $sessionId => $coachList) {
5919
                    $sessionInfo = self::fetch($sessionId);
5920
                    $htmlResult .= '<br />';
5921
                    $htmlResult .= Display::url(
5922
                        get_lang('Session').': '.$sessionInfo['name'].' <br />',
5923
                        $sessionUrl.$sessionId,
5924
                        ['target' => '_blank']
5925
                    );
5926
                    $teacherList = [];
5927
                    foreach ($coachList as $coachId) {
5928
                        $userInfo = api_get_user_info($coachId);
5929
                        $teacherList[] = $userInfo['complete_name'];
5930
                    }
5931
                    if (!empty($teacherList)) {
5932
                        $htmlResult .= implode(', ', $teacherList);
5933
                    } else {
5934
                        $htmlResult .= get_lang('NothingToAdd');
5935
                    }
5936
                }
5937
                $htmlResult .= '<br />';
5938
            }
5939
            $htmlResult = Display::return_message($htmlResult, 'normal', false);
5940
        }
5941
        return $htmlResult;
5942
    }
5943
5944
    /**
5945
     * @param string $keyword
5946
     * @param string $active
5947
     * @param string $lastConnectionDate
5948
     * @param array $sessionIdList
5949
     * @param array $studentIdList
5950
     * @param int $filterUserStatus STUDENT|COURSEMANAGER constants
5951
     *
5952
     * @return array|int
5953
     */
5954
    public static function getCountUserTracking(
5955
        $keyword = null,
5956
        $active = null,
5957
        $lastConnectionDate = null,
5958
        $sessionIdList = [],
5959
        $studentIdList = [],
5960
        $filterUserStatus = null
5961
    ) {
5962
        $userId = api_get_user_id();
5963
        $drhLoaded = false;
5964
5965
        if (api_is_drh()) {
5966
            if (api_drh_can_access_all_session_content()) {
5967
                $count = self::getAllUsersFromCoursesFromAllSessionFromStatus(
5968
                    'drh_all',
5969
                    $userId,
5970
                    true,
5971
                    null,
5972
                    null,
5973
                    null,
5974
                    null,
5975
                    $keyword,
5976
                    $active,
5977
                    $lastConnectionDate,
5978
                    $sessionIdList,
5979
                    $studentIdList,
5980
                    $filterUserStatus
5981
                );
5982
                $drhLoaded = true;
5983
            }
5984
        }
5985
5986
        if ($drhLoaded == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
5987
            $count = UserManager::getUsersFollowedByUser(
5988
                $userId,
5989
                $filterUserStatus,
5990
                false,
5991
                false,
5992
                true,
5993
                null,
5994
                null,
5995
                null,
5996
                null,
5997
                $active,
0 ignored issues
show
Bug introduced by
It seems like $active can also be of type string; however, parameter $active of UserManager::getUsersFollowedByUser() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

5997
                /** @scrutinizer ignore-type */ $active,
Loading history...
5998
                $lastConnectionDate,
5999
                api_is_student_boss() ? STUDENT_BOSS : COURSEMANAGER,
6000
                $keyword
6001
            );
6002
        }
6003
6004
        return $count;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $count does not seem to be defined for all execution paths leading up to this point.
Loading history...
6005
    }
6006
6007
    /**
6008
     * Get teachers followed by a user
6009
     * @param int $userId
6010
     * @param int $active
6011
     * @param string $lastConnectionDate
6012
     * @param bool $getCount
6013
     * @param array $sessionIdList
6014
     * @return array|int
6015
     */
6016
    public static function getTeacherTracking(
6017
        $userId,
6018
        $active = 1,
6019
        $lastConnectionDate = null,
6020
        $getCount = false,
6021
        $sessionIdList = []
6022
    ) {
6023
        $teacherListId = [];
6024
        if (api_is_drh() || api_is_platform_admin()) {
6025
            // Followed teachers by drh
6026
            if (api_drh_can_access_all_session_content()) {
6027
                if (empty($sessionIdList)) {
6028
                    $sessions = self::get_sessions_followed_by_drh($userId);
6029
                    $sessionIdList = [];
6030
                    foreach ($sessions as $session) {
6031
                        $sessionIdList[] = $session['id'];
6032
                    }
6033
                }
6034
6035
                $sessionIdList = array_map('intval', $sessionIdList);
6036
                $sessionToString = implode("', '", $sessionIdList);
6037
6038
                $course = Database::get_main_table(TABLE_MAIN_COURSE);
6039
                $sessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6040
                $courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
6041
6042
                // Select the teachers.
6043
                $sql = "SELECT DISTINCT(cu.user_id) 
6044
                        FROM $course c
6045
                        INNER JOIN $sessionCourse src 
6046
                        ON c.id = src.c_id
6047
                        INNER JOIN $courseUser cu 
6048
                        ON (cu.c_id = c.id)
6049
		                WHERE src.session_id IN ('$sessionToString') AND cu.status = 1";
6050
                $result = Database::query($sql);
6051
                while ($row = Database::fetch_array($result, 'ASSOC')) {
6052
                    $teacherListId[$row['user_id']] = $row['user_id'];
6053
                }
6054
            } else {
6055
                $teacherResult = UserManager::get_users_followed_by_drh($userId, COURSEMANAGER);
6056
                foreach ($teacherResult as $userInfo) {
6057
                    $teacherListId[] = $userInfo['user_id'];
6058
                }
6059
            }
6060
        }
6061
6062
        if (!empty($teacherListId)) {
6063
            $tableUser = Database::get_main_table(TABLE_MAIN_USER);
6064
6065
            $select = "SELECT DISTINCT u.* ";
6066
            if ($getCount) {
6067
                $select = "SELECT count(DISTINCT(u.user_id)) as count";
6068
            }
6069
6070
            $sql = "$select FROM $tableUser u";
6071
6072
            if (!empty($lastConnectionDate)) {
6073
                $tableLogin = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
6074
                //$sql .= " INNER JOIN $tableLogin l ON (l.login_user_id = u.user_id) ";
6075
            }
6076
            $active = intval($active);
6077
            $teacherListId = implode("','", $teacherListId);
6078
            $where = " WHERE u.active = $active AND u.user_id IN ('$teacherListId') ";
6079
6080
            if (!empty($lastConnectionDate)) {
6081
                $lastConnectionDate = Database::escape_string($lastConnectionDate);
6082
                //$where .= " AND l.login_date <= '$lastConnectionDate' ";
6083
            }
6084
6085
            $sql .= $where;
6086
            $result = Database::query($sql);
6087
            if (Database::num_rows($result)) {
6088
                if ($getCount) {
6089
                    $row = Database::fetch_array($result);
6090
                    return $row['count'];
6091
                } else {
6092
                    return Database::store_result($result, 'ASSOC');
6093
                }
6094
            }
6095
        }
6096
6097
        return 0;
6098
    }
6099
6100
    /**
6101
     * Get the list of course tools that have to be dealt with in case of
6102
     * registering any course to a session
6103
     * @return array The list of tools to be dealt with (literal names)
6104
     */
6105
    public static function getCourseToolToBeManaged()
6106
    {
6107
        return [
6108
            'courseDescription',
6109
            'courseIntroduction',
6110
        ];
6111
    }
6112
6113
    /**
6114
     * Calls the methods bound to each tool when a course is registered into a session
6115
     * @param int $sessionId
6116
     * @param int $courseId
6117
     * @return bool
6118
     */
6119
    public static function installCourse($sessionId, $courseId)
6120
    {
6121
        return true;
6122
        $toolList = self::getCourseToolToBeManaged();
0 ignored issues
show
Unused Code introduced by
$toolList = self::getCourseToolToBeManaged() is not 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...
6123
6124
        foreach ($toolList as $tool) {
6125
            $method = 'add'.$tool;
6126
            if (method_exists(get_class(), $method)) {
6127
                self::$method($sessionId, $courseId);
6128
            }
6129
        }
6130
    }
6131
6132
    /**
6133
     * Calls the methods bound to each tool when a course is unregistered from
6134
     * a session
6135
     * @param int $sessionId
6136
     * @param int $courseId
6137
     */
6138
    public static function unInstallCourse($sessionId, $courseId)
6139
    {
6140
        return true;
6141
        $toolList = self::getCourseToolToBeManaged();
0 ignored issues
show
Unused Code introduced by
$toolList = self::getCourseToolToBeManaged() is not 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...
6142
6143
        foreach ($toolList as $tool) {
6144
            $method = 'remove'.$tool;
6145
            if (method_exists(get_class(), $method)) {
6146
                self::$method($sessionId, $courseId);
6147
            }
6148
        }
6149
    }
6150
6151
    /**
6152
     * @param int $sessionId
6153
     * @param int $courseId
6154
     */
6155
    public static function addCourseIntroduction($sessionId, $courseId)
6156
    {
6157
        // @todo create a tool intro lib
6158
        $sessionId = intval($sessionId);
6159
        $courseId = intval($courseId);
6160
6161
        $TBL_INTRODUCTION = Database::get_course_table(TABLE_TOOL_INTRO);
6162
        $sql = "SELECT * FROM $TBL_INTRODUCTION WHERE c_id = $courseId";
6163
        $result = Database::query($sql);
6164
        $result = Database::store_result($result, 'ASSOC');
6165
6166
        if (!empty($result)) {
6167
            foreach ($result as $result) {
6168
                // @todo check if relation exits.
6169
                $result['session_id'] = $sessionId;
6170
                Database::insert($TBL_INTRODUCTION, $result);
6171
            }
6172
        }
6173
    }
6174
6175
    /**
6176
     * @param int $sessionId
6177
     * @param int $courseId
6178
     */
6179
    public static function removeCourseIntroduction($sessionId, $courseId)
6180
    {
6181
        $sessionId = intval($sessionId);
6182
        $courseId = intval($courseId);
6183
        $TBL_INTRODUCTION = Database::get_course_table(TABLE_TOOL_INTRO);
6184
        $sql = "DELETE FROM $TBL_INTRODUCTION
6185
                WHERE c_id = $courseId AND session_id = $sessionId";
6186
        Database::query($sql);
6187
    }
6188
6189
    /**
6190
     * @param int $sessionId
6191
     * @param int $courseId
6192
     */
6193
    public static function addCourseDescription($sessionId, $courseId)
6194
    {
6195
        /* $description = new CourseDescription();
6196
          $descriptions = $description->get_descriptions($courseId);
6197
          foreach ($descriptions as $description) {
6198
          } */
6199
    }
6200
6201
    /**
6202
     * @param int $sessionId
6203
     * @param int $courseId
6204
     */
6205
    public static function removeCourseDescription($sessionId, $courseId)
6206
    {
6207
    }
6208
6209
    /**
6210
     * @param array $userSessionList format see self::importSessionDrhCSV()
6211
     * @param bool $sendEmail
6212
     * @param bool $removeOldRelationShips
6213
     */
6214
    public static function subscribeDrhToSessionList(
6215
        $userSessionList,
6216
        $sendEmail,
6217
        $removeOldRelationShips
6218
    ) {
6219
        if (!empty($userSessionList)) {
6220
            foreach ($userSessionList as $userId => $data) {
6221
                $sessionList = [];
6222
                foreach ($data['session_list'] as $sessionInfo) {
6223
                    $sessionList[] = $sessionInfo['session_id'];
6224
                }
6225
                $userInfo = $data['user_info'];
6226
                self::subscribeSessionsToDrh(
6227
                    $userInfo,
6228
                    $sessionList,
6229
                    $sendEmail,
6230
                    $removeOldRelationShips
6231
                );
6232
            }
6233
        }
6234
    }
6235
6236
    /**
6237
     * @param array $userSessionList format see self::importSessionDrhCSV()
6238
     *
6239
     * @return string
6240
     */
6241
    public static function checkSubscribeDrhToSessionList($userSessionList)
6242
    {
6243
        $message = null;
6244
        if (!empty($userSessionList)) {
6245
            if (!empty($userSessionList)) {
6246
                foreach ($userSessionList as $userId => $data) {
6247
                    $userInfo = $data['user_info'];
6248
6249
                    $sessionListSubscribed = self::get_sessions_followed_by_drh($userId);
6250
                    if (!empty($sessionListSubscribed)) {
6251
                        $sessionListSubscribed = array_keys($sessionListSubscribed);
6252
                    }
6253
6254
                    $sessionList = [];
6255
                    if (!empty($data['session_list'])) {
6256
                        foreach ($data['session_list'] as $sessionInfo) {
6257
                            if (in_array($sessionInfo['session_id'], $sessionListSubscribed)) {
6258
                                $sessionList[] = $sessionInfo['session_info']['name'];
6259
                            }
6260
                        }
6261
                    }
6262
6263
                    $message .= '<strong>'.get_lang('User').'</strong>: '.$userInfo['complete_name'].' <br />';
6264
6265
                    if (!in_array($userInfo['status'], [DRH]) && !api_is_platform_admin_by_id($userInfo['user_id'])) {
6266
                        $message .= get_lang('UserMustHaveTheDrhRole').'<br />';
6267
                        continue;
6268
                    }
6269
6270
                    if (!empty($sessionList)) {
6271
                        $message .= '<strong>'.get_lang('Sessions').':</strong> <br />';
6272
                        $message .= implode(', ', $sessionList).'<br /><br />';
6273
                    } else {
6274
                        $message .= get_lang('NoSessionProvided').' <br /><br />';
6275
                    }
6276
                }
6277
            }
6278
        }
6279
6280
        return $message;
6281
    }
6282
6283
    /**
6284
     * @param string $file
6285
     * @param bool $sendEmail
6286
     * @param bool $removeOldRelationShips
6287
     *
6288
     * @return string
6289
     */
6290
    public static function importSessionDrhCSV($file, $sendEmail, $removeOldRelationShips)
6291
    {
6292
        $list = Import::csv_reader($file);
6293
6294
        if (!empty($list)) {
6295
            $userSessionList = [];
6296
            foreach ($list as $data) {
6297
                $userInfo = api_get_user_info_from_username($data['Username']);
6298
                $sessionInfo = self::get_session_by_name($data['SessionName']);
6299
6300
                if (!empty($userInfo) && !empty($sessionInfo)) {
6301
                    $userSessionList[$userInfo['user_id']]['session_list'][] = [
6302
                        'session_id' => $sessionInfo['id'],
6303
                        'session_info' => $sessionInfo,
6304
                    ];
6305
                    $userSessionList[$userInfo['user_id']]['user_info'] = $userInfo;
6306
                }
6307
            }
6308
6309
            self::subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips);
6310
            return self::checkSubscribeDrhToSessionList($userSessionList);
6311
        }
6312
    }
6313
6314
    /**
6315
     * Courses re-ordering in resume_session.php flag see BT#8316
6316
     */
6317
    public static function orderCourseIsEnabled()
6318
    {
6319
        $sessionCourseOrder = api_get_setting('session_course_ordering');
6320
        if ($sessionCourseOrder === 'true') {
6321
            return true;
6322
        }
6323
6324
        return false;
6325
    }
6326
6327
    /**
6328
     * @param string $direction (up/down)
6329
     * @param int $sessionId
6330
     * @param int $courseId
6331
     * @return bool
6332
     */
6333
    public static function move($direction, $sessionId, $courseId)
6334
    {
6335
        if (!self::orderCourseIsEnabled()) {
6336
            return false;
6337
        }
6338
6339
        $sessionId = intval($sessionId);
6340
        $courseId = intval($courseId);
6341
6342
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6343
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
6344
6345
        $position = [];
6346
        $count = 0;
6347
        foreach ($courseList as $course) {
6348
            if ($course['position'] == '') {
6349
                $course['position'] = $count;
6350
            }
6351
            $position[$course['code']] = $course['position'];
6352
            // Saving current order.
6353
            $sql = "UPDATE $table SET position = $count
6354
                    WHERE session_id = $sessionId AND c_id = '".$course['real_id']."'";
6355
            Database::query($sql);
6356
            $count++;
6357
        }
6358
6359
        // Loading new positions.
6360
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
6361
6362
        $found = false;
6363
6364
        switch ($direction) {
6365
            case 'up':
6366
                $courseList = array_reverse($courseList);
0 ignored issues
show
Bug introduced by
It seems like $courseList can also be of type integer; however, parameter $array of array_reverse() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

6366
                $courseList = array_reverse(/** @scrutinizer ignore-type */ $courseList);
Loading history...
6367
                break;
6368
            case 'down':
6369
                break;
6370
        }
6371
6372
        foreach ($courseList as $course) {
6373
            if ($found) {
6374
                $nextId = $course['real_id'];
6375
                $nextOrder = $course['position'];
6376
                break;
6377
            }
6378
6379
            if ($courseId == $course['real_id']) {
6380
                $thisCourseCode = $course['real_id'];
6381
                $thisOrder = $course['position'];
6382
                $found = true;
6383
            }
6384
        }
6385
6386
        $sql1 = "UPDATE $table SET position = '".intval($nextOrder)."'
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $nextOrder does not seem to be defined for all execution paths leading up to this point.
Loading history...
6387
                 WHERE session_id = $sessionId AND c_id =  $thisCourseCode";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $thisCourseCode does not seem to be defined for all execution paths leading up to this point.
Loading history...
6388
        Database::query($sql1);
6389
6390
        $sql2 = "UPDATE $table SET position = '".intval($thisOrder)."'
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $thisOrder does not seem to be defined for all execution paths leading up to this point.
Loading history...
6391
                 WHERE session_id = $sessionId AND c_id = $nextId";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $nextId does not seem to be defined for all execution paths leading up to this point.
Loading history...
6392
        Database::query($sql2);
6393
6394
        return true;
6395
    }
6396
6397
    /**
6398
     * @param int $sessionId
6399
     * @param int $courseId
6400
     * @return bool
6401
     */
6402
    public static function moveUp($sessionId, $courseId)
6403
    {
6404
        return self::move('up', $sessionId, $courseId);
6405
    }
6406
6407
    /**
6408
     * @param int $sessionId
6409
     * @param string $courseCode
6410
     * @return bool
6411
     */
6412
    public static function moveDown($sessionId, $courseCode)
6413
    {
6414
        return self::move('down', $sessionId, $courseCode);
6415
    }
6416
6417
    /**
6418
     * Use the session duration to allow/block user access see BT#8317
6419
     * Needs these DB changes
6420
     * ALTER TABLE session ADD COLUMN duration int;
6421
     * ALTER TABLE session_rel_user ADD COLUMN duration int;
6422
     */
6423
    public static function durationPerUserIsEnabled()
6424
    {
6425
        return api_get_configuration_value('session_duration_feature');
6426
    }
6427
6428
    /**
6429
     * Returns the number of days the student has left in a session when using
6430
     * sessions durations
6431
     * @param array $sessionInfo
6432
     * @param int $userId
6433
     * @return int
6434
     */
6435
    public static function getDayLeftInSession(array $sessionInfo, $userId)
6436
    {
6437
        $sessionId = $sessionInfo['id'];
6438
        $subscription = self::getUserSession($userId, $sessionId);
6439
        $duration = empty($subscription['duration'])
6440
            ? $sessionInfo['duration']
6441
            : $sessionInfo['duration'] + $subscription['duration'];
6442
6443
        // Get an array with the details of the first access of the student to
6444
        // this session
6445
        $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
6446
            $sessionId,
6447
            $userId
6448
        );
6449
6450
        $currentTime = time();
6451
6452
        // If no previous access, return false
6453
        if (count($courseAccess) == 0) {
6454
            return $duration;
6455
        }
6456
6457
        $firstAccess = api_strtotime($courseAccess['login_course_date'], 'UTC');
6458
        $endDateInSeconds = $firstAccess + $duration * 24 * 60 * 60;
6459
        $leftDays = round(($endDateInSeconds - $currentTime) / 60 / 60 / 24);
6460
6461
        return $leftDays;
6462
    }
6463
6464
    /**
6465
     * @param int $duration
6466
     * @param int $userId
6467
     * @param int $sessionId
6468
     *
6469
     * @return bool
6470
     */
6471
    public static function editUserSessionDuration($duration, $userId, $sessionId)
6472
    {
6473
        $duration = intval($duration);
6474
        $userId = intval($userId);
6475
        $sessionId = intval($sessionId);
6476
6477
        if (empty($userId) || empty($sessionId)) {
6478
            return false;
6479
        }
6480
6481
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6482
        $parameters = ['duration' => $duration];
6483
        $where = ['session_id = ? AND user_id = ? ' => [$sessionId, $userId]];
6484
        Database::update($table, $parameters, $where);
6485
        return true;
6486
    }
6487
6488
    /**
6489
     * Gets one row from the session_rel_user table
6490
     * @param int $userId
6491
     * @param int $sessionId
6492
     *
6493
     * @return array
6494
     */
6495
    public static function getUserSession($userId, $sessionId)
6496
    {
6497
        $userId = intval($userId);
6498
        $sessionId = intval($sessionId);
6499
6500
        if (empty($userId) || empty($sessionId)) {
6501
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type array.
Loading history...
6502
        }
6503
6504
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6505
        $sql = "SELECT * FROM $table
6506
                WHERE session_id = $sessionId AND user_id = $userId";
6507
        $result = Database::query($sql);
6508
        $values = [];
6509
        if (Database::num_rows($result)) {
6510
            $values = Database::fetch_array($result, 'ASSOC');
6511
        }
6512
6513
        return $values;
6514
    }
6515
6516
    /**
6517
     * Check if user is subscribed inside a session as student
6518
     * @param int $sessionId The session id
6519
     * @param int $userId The user id
6520
     * @return boolean Whether is subscribed
6521
     */
6522
    public static function isUserSubscribedAsStudent($sessionId, $userId)
6523
    {
6524
        $sessionRelUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6525
        $sessionId = intval($sessionId);
6526
        $userId = intval($userId);
6527
6528
        // COUNT(1) actually returns the number of rows from the table (as if
6529
        // counting the results from the first column)
6530
        $sql = "SELECT COUNT(1) AS qty FROM $sessionRelUserTable
6531
                WHERE
6532
                    session_id = $sessionId AND
6533
                    user_id = $userId AND
6534
                    relation_type = 0";
6535
6536
        $result = Database::fetch_assoc(Database::query($sql));
6537
6538
        if (!empty($result) && $result['qty'] > 0) {
6539
            return true;
6540
        }
6541
6542
        return false;
6543
    }
6544
6545
    /**
6546
     * Check if user is subscribed inside a session as a HRM
6547
     * @param int $sessionId The session id
6548
     * @param int $userId The user id
6549
     * @return boolean Whether is subscribed
6550
     */
6551
    public static function isUserSubscribedAsHRM($sessionId, $userId)
6552
    {
6553
        $sessionRelUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6554
6555
        $sessionId = intval($sessionId);
6556
        $userId = intval($userId);
6557
6558
        // COUNT(1) actually returns the number of rows from the table (as if
6559
        // counting the results from the first column)
6560
        $sql = "SELECT COUNT(1) AS qty FROM $sessionRelUserTable
6561
                WHERE
6562
                    session_id = $sessionId AND
6563
                    user_id = $userId AND
6564
                    relation_type = ".SESSION_RELATION_TYPE_RRHH;
6565
6566
        $result = Database::fetch_assoc(Database::query($sql));
6567
6568
        if (!empty($result) && $result['qty'] > 0) {
6569
            return true;
6570
        }
6571
6572
        return false;
6573
    }
6574
6575
    /**
6576
     * Get the session coached by a user (general coach and course-session coach)
6577
     * @param int $coachId The coach id
6578
     * @param boolean $checkSessionRelUserVisibility Check the session visibility
6579
     * @param boolean $asPlatformAdmin The user is a platform admin and we want all sessions
6580
     * @return array The session list
6581
     */
6582
    public static function getSessionsCoachedByUser(
6583
        $coachId,
6584
        $checkSessionRelUserVisibility = false,
6585
        $asPlatformAdmin = false
6586
    ) {
6587
        // Get all sessions where $coachId is the general coach
6588
        $sessions = self::get_sessions_by_general_coach($coachId, $asPlatformAdmin);
6589
        // Get all sessions where $coachId is the course - session coach
6590
        $courseSessionList = self::getCoursesListByCourseCoach($coachId);
6591
        $sessionsByCoach = [];
6592
        if (!empty($courseSessionList)) {
6593
            foreach ($courseSessionList as $userCourseSubscription) {
6594
                $session = $userCourseSubscription->getSession();
6595
                $sessionsByCoach[$session->getId()] = api_get_session_info(
6596
                    $session->getId()
6597
                );
6598
            }
6599
        }
6600
6601
        if (!empty($sessionsByCoach)) {
6602
            $sessions = array_merge($sessions, $sessionsByCoach);
6603
        }
6604
6605
        // Remove repeated sessions
6606
        if (!empty($sessions)) {
6607
            $cleanSessions = [];
6608
            foreach ($sessions as $session) {
6609
                $cleanSessions[$session['id']] = $session;
6610
            }
6611
            $sessions = $cleanSessions;
6612
        }
6613
6614
        if ($checkSessionRelUserVisibility) {
6615
            if (!empty($sessions)) {
6616
                $newSessions = [];
6617
                foreach ($sessions as $session) {
6618
                    $visibility = api_get_session_visibility($session['id']);
6619
                    if ($visibility == SESSION_INVISIBLE) {
6620
                        continue;
6621
                    }
6622
                    $newSessions[] = $session;
6623
                }
6624
                $sessions = $newSessions;
6625
            }
6626
        }
6627
6628
        return $sessions;
6629
    }
6630
6631
    /**
6632
     * Check if the course belongs to the session
6633
     * @param int $sessionId The session id
6634
     * @param string $courseCode The course code
6635
     *
6636
     * @return bool
6637
     */
6638
    public static function sessionHasCourse($sessionId, $courseCode)
6639
    {
6640
        $sessionId = intval($sessionId);
6641
        $courseCode = Database::escape_string($courseCode);
6642
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
6643
        $sessionRelCourseTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6644
6645
        $sql = "SELECT COUNT(1) AS qty
6646
                FROM $courseTable c
6647
                INNER JOIN $sessionRelCourseTable src
6648
                ON c.id = src.c_id
6649
                WHERE src.session_id = $sessionId
6650
                AND c.code = '$courseCode'  ";
6651
6652
        $result = Database::query($sql);
6653
6654
        if ($result !== false) {
6655
            $data = Database::fetch_assoc($result);
6656
6657
            if ($data['qty'] > 0) {
6658
                return true;
6659
            }
6660
        }
6661
6662
        return false;
6663
    }
6664
6665
    /**
6666
     * Get the list of course coaches
6667
     * @return array The list
6668
     */
6669
    public static function getAllCourseCoaches()
6670
    {
6671
        $coaches = [];
6672
6673
        $scuTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6674
        $userTable = Database::get_main_table(TABLE_MAIN_USER);
6675
6676
        $idResult = Database::select('DISTINCT user_id', $scuTable, [
6677
            'where' => [
6678
                'status = ?' => 2,
6679
            ],
6680
        ]);
6681
6682
        if ($idResult != false) {
6683
            foreach ($idResult as $idData) {
6684
                $userResult = Database::select(
6685
                    'user_id, lastname, firstname, username',
6686
                    $userTable,
6687
                    [
6688
                        'where' => [
6689
                            'user_id = ?' => $idData['user_id'],
6690
                        ],
6691
                    ],
6692
                    'first'
6693
                );
6694
6695
                if ($userResult != false) {
6696
                    $coaches[] = [
6697
                        'id' => $userResult['user_id'],
6698
                        'lastname' => $userResult['lastname'],
6699
                        'firstname' => $userResult['firstname'],
6700
                        'username' => $userResult['username'],
6701
                        'completeName' => api_get_person_name(
6702
                            $userResult['firstname'],
6703
                            $userResult['lastname']
6704
                        ),
6705
                    ];
6706
                }
6707
            }
6708
        }
6709
6710
        return $coaches;
6711
    }
6712
6713
    /**
6714
     * Calculate the total user time in the platform
6715
     * @param int $userId The user id
6716
     * @param string $from Optional. From date
6717
     * @param string $until Optional. Until date
6718
     * @return string The time (hh:mm:ss)
6719
     */
6720
    public static function getTotalUserTimeInPlatform($userId, $from = '', $until = '')
6721
    {
6722
        $userId = intval($userId);
6723
        $trackLoginTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
6724
        $whereConditions = [
6725
            'login_user_id = ? ' => $userId,
6726
        ];
6727
6728
        if (!empty($from) && !empty($until)) {
6729
            $whereConditions["AND (login_date >= '?' "] = $from;
6730
            $whereConditions["AND logout_date <= DATE_ADD('?', INTERVAL 1 DAY)) "] = $until;
6731
        }
6732
6733
        $trackResult = Database::select(
6734
            'SEC_TO_TIME(SUM(UNIX_TIMESTAMP(logout_date) - UNIX_TIMESTAMP(login_date))) as total_time',
6735
            $trackLoginTable,
6736
            [
6737
                'where' => $whereConditions,
6738
            ],
6739
            'first'
6740
        );
6741
6742
        if ($trackResult != false) {
6743
            return $trackResult['total_time'] ? $trackResult['total_time'] : '00:00:00';
6744
        }
6745
6746
        return '00:00:00';
6747
    }
6748
6749
    /**
6750
     * Get the courses list by a course coach
6751
     * @param int $coachId The coach id
6752
     * @return array (id, user_id, session_id, c_id, visibility, status, legal_agreement)
6753
     */
6754
    public static function getCoursesListByCourseCoach($coachId)
6755
    {
6756
        $entityManager = Database::getManager();
6757
        $scuRepo = $entityManager->getRepository(
6758
            'ChamiloCoreBundle:SessionRelCourseRelUser'
6759
        );
6760
6761
        return $scuRepo->findBy([
6762
            'user' => $coachId,
6763
            'status' => SessionRelCourseRelUser::STATUS_COURSE_COACH,
6764
        ]);
6765
    }
6766
6767
    /**
6768
     * Get the count of user courses in session
6769
     * @param int $sessionId The session id
6770
     * @return array
6771
     */
6772
    public static function getTotalUserCoursesInSession($sessionId)
6773
    {
6774
        $tableUser = Database::get_main_table(TABLE_MAIN_USER);
6775
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6776
6777
        if (empty($sessionId)) {
6778
            return [];
6779
        }
6780
6781
        $sql = "SELECT 
6782
                    COUNT(u.id) as count, 
6783
                    u.id, 
6784
                    scu.status status_in_session, 
6785
                    u.status user_status
6786
                FROM $table scu
6787
                INNER JOIN $tableUser u 
6788
                ON scu.user_id = u.id
6789
                WHERE scu.session_id = ".intval($sessionId)."
6790
                GROUP BY u.id";
6791
6792
        $result = Database::query($sql);
6793
6794
        $list = [];
6795
        while ($data = Database::fetch_assoc($result)) {
6796
            $list[] = $data;
6797
        }
6798
6799
        return $list;
6800
    }
6801
6802
    /**
6803
     * Returns list of a few data from session (name, short description, start
6804
     * date, end date) and the given extra fields if defined based on a
6805
     * session category Id.
6806
     * @param int $categoryId The internal ID of the session category
6807
     * @param string $target Value to search for in the session field values
6808
     * @param array $extraFields A list of fields to be scanned and returned
6809
     * @return mixed
6810
     */
6811
    public static function getShortSessionListAndExtraByCategory(
6812
        $categoryId,
6813
        $target,
6814
        $extraFields = null,
6815
        $publicationDate = null
6816
    ) {
6817
        $categoryId = (int) $categoryId;
6818
        $sessionList = [];
6819
        // Check if categoryId is valid
6820
        if ($categoryId > 0) {
6821
            $target = Database::escape_string($target);
6822
            $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
6823
            $sfTable = Database::get_main_table(TABLE_EXTRA_FIELD);
6824
            $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
6825
            // Join session field and session field values tables
6826
            $joinTable = $sfTable.' sf INNER JOIN '.$sfvTable.' sfv ON sf.id = sfv.field_id';
6827
            $fieldsArray = [];
6828
            foreach ($extraFields as $field) {
6829
                $fieldsArray[] = Database::escape_string($field);
6830
            }
6831
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
6832
            if (isset($publicationDate)) {
6833
                $publicationDateString = $publicationDate->format('Y-m-d H:i:s');
6834
                $wherePublication = " AND id NOT IN (
6835
                    SELECT sfv.item_id FROM $joinTable
6836
                    WHERE
6837
                        sf.extra_field_type = $extraFieldType AND
6838
                        ((sf.variable = 'publication_start_date' AND sfv.value > '$publicationDateString' and sfv.value != '') OR
6839
                        (sf.variable = 'publication_end_date' AND sfv.value < '$publicationDateString' and sfv.value != ''))
6840
                )";
6841
            }
6842
            // Get the session list from session category and target
6843
            $sessionList = Database::select(
6844
                'id, name, access_start_date, access_end_date',
6845
                $sTable,
6846
                [
6847
                    'where' => [
6848
                        "session_category_id = ? AND id IN (
6849
                            SELECT sfv.item_id FROM $joinTable
6850
                            WHERE
6851
                                sf.extra_field_type = $extraFieldType AND
6852
                                sfv.item_id = session.id AND
6853
                                sf.variable = 'target' AND
6854
                                sfv.value = ?
6855
                        ) $wherePublication" => [$categoryId, $target],
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $wherePublication does not seem to be defined for all execution paths leading up to this point.
Loading history...
6856
                    ],
6857
                ]
6858
            );
6859
            $whereFieldVariables = [];
6860
            $whereFieldIds = [];
6861
            if (
6862
                is_array($fieldsArray) &&
6863
                count($fieldsArray) > 0
6864
            ) {
6865
                $whereParams = '?';
6866
                for ($i = 1; $i < count($fieldsArray); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
6867
                    $whereParams .= ', ?';
6868
                }
6869
                $whereFieldVariables = ' variable IN ( '.$whereParams.' )';
6870
                $whereFieldIds = 'field_id IN ( '.$whereParams.' )';
6871
            }
6872
            // Get session fields
6873
            $extraField = new ExtraFieldModel('session');
6874
            $questionMarks = substr(str_repeat('?, ', count($fieldsArray)), 0, -2);
6875
            $fieldsList = $extraField->get_all([
6876
                ' variable IN ( '.$questionMarks.' )' => $fieldsArray,
6877
            ]);
6878
            // Index session fields
6879
            foreach ($fieldsList as $field) {
6880
                $fields[$field['id']] = $field['variable'];
6881
            }
6882
            // Get session field values
6883
            $extra = new ExtraFieldValue('session');
6884
            $questionMarksFields = substr(str_repeat('?, ', count($fields)), 0, -2);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $fields seems to be defined by a foreach iteration on line 6879. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
6885
            $sessionFieldValueList = $extra->get_all(['where' => ['field_id IN ( '.$questionMarksFields.' )' => array_keys($fields)]]);
6886
            // Add session fields values to session list
6887
            foreach ($sessionList as $id => &$session) {
6888
                foreach ($sessionFieldValueList as $sessionFieldValue) {
6889
                    // Match session field values to session
6890
                    if ($sessionFieldValue['item_id'] == $id) {
6891
                        // Check if session field value is set in session field list
6892
                        if (isset($fields[$sessionFieldValue['field_id']])) {
6893
                            // Avoid overwriting the session's ID field
6894
                            if ($fields[$sessionFieldValue['field_id']] != 'id') {
6895
                                $var = $fields[$sessionFieldValue['field_id']];
6896
                                $val = $sessionFieldValue['value'];
6897
                                // Assign session field value to session
6898
                                $session[$var] = $val;
6899
                            }
6900
                        }
6901
                    }
6902
                }
6903
            }
6904
        }
6905
6906
        return $sessionList;
6907
    }
6908
6909
    /**
6910
     * Return the Session Category id searched by name
6911
     * @param string $categoryName Name attribute of session category used for search query
6912
     * @param bool $force boolean used to get even if something is wrong (e.g not unique name)
6913
     * @return int|array If success, return category id (int), else it will return an array
6914
     * with the next structure:
6915
     * array('error' => true, 'errorMessage' => ERROR_MESSAGE)
6916
     */
6917
    public static function getSessionCategoryIdByName($categoryName, $force = false)
6918
    {
6919
        // Start error result
6920
        $errorResult = ['error' => true, 'errorMessage' => get_lang('ThereWasAnError')];
6921
        $categoryName = Database::escape_string($categoryName);
6922
        // Check if is not empty category name
6923
        if (!empty($categoryName)) {
6924
            $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
6925
            // Get all session category with same name
6926
            $result = Database::select(
6927
                'id',
6928
                $sessionCategoryTable,
6929
                [
6930
                    'where' => [
6931
                        'name = ?' => $categoryName,
6932
                    ],
6933
                ]
6934
            );
6935
            // Check the result
6936
            if ($result < 1) {
6937
                // If not found any result, update error message
6938
                $errorResult['errorMessage'] = 'Not found any session category name '.$categoryName;
6939
            } elseif (count($result) > 1 && !$force) {
6940
                // If found more than one result and force is disabled, update error message
6941
                $errorResult['errorMessage'] = 'Found many session categories';
6942
            } elseif (count($result) == 1 || $force) {
6943
                // If found just one session category or force option is enabled
6944
6945
                return key($result);
0 ignored issues
show
Bug Best Practice introduced by
The expression return key($result) also could return the type string which is incompatible with the documented return type integer|array.
Loading history...
6946
            }
6947
        } else {
6948
            // category name is empty, update error message
6949
            $errorResult['errorMessage'] = 'Not valid category name';
6950
        }
6951
6952
        return $errorResult;
6953
    }
6954
6955
    /**
6956
     * Return all data from sessions (plus extra field, course and coach data) by category id
6957
     * @param int $sessionCategoryId session category id used to search sessions
6958
     * @return array If success, return session list and more session related data, else it will return an array
6959
     * with the next structure:
6960
     * array('error' => true, 'errorMessage' => ERROR_MESSAGE)
6961
     */
6962
    public static function getSessionListAndExtraByCategoryId($sessionCategoryId)
6963
    {
6964
        // Start error result
6965
        $errorResult = [
6966
            'error' => true,
6967
            'errorMessage' => get_lang('ThereWasAnError'),
6968
        ];
6969
6970
        $sessionCategoryId = intval($sessionCategoryId);
6971
        // Check if session category id is valid
6972
        if ($sessionCategoryId > 0) {
6973
            // Get table names
6974
            $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
6975
            $sessionFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
6976
            $sessionFieldValueTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
6977
            $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6978
            $userTable = Database::get_main_table(TABLE_MAIN_USER);
6979
            $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
6980
6981
            // Get all data from all sessions whit the session category specified
6982
            $sessionList = Database::select(
6983
                '*',
6984
                $sessionTable,
6985
                [
6986
                    'where' => [
6987
                        'session_category_id = ?' => $sessionCategoryId,
6988
                    ],
6989
                ]
6990
            );
6991
6992
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
6993
6994
            // Check if session list query had result
6995
            if (!empty($sessionList)) {
6996
                // implode all session id
6997
                $sessionIdsString = '('.implode(', ', array_keys($sessionList)).')';
6998
                // Get all field variables
6999
                $sessionFieldList = Database::select(
7000
                    'id, variable',
7001
                    $sessionFieldTable,
7002
                    ['extra_field_type = ? ' => [$extraFieldType]]
7003
                );
7004
7005
                // Get all field values
7006
                $sql = "SELECT item_id, field_id, value FROM
7007
                        $sessionFieldValueTable v INNER JOIN $sessionFieldTable f
7008
                        ON (f.id = v.field_id)
7009
                        WHERE
7010
                            item_id IN $sessionIdsString AND
7011
                            extra_field_type = $extraFieldType
7012
                ";
7013
                $result = Database::query($sql);
7014
                $sessionFieldValueList = Database::store_result($result, 'ASSOC');
7015
7016
                // Check if session field values had result
7017
                if (!empty($sessionFieldValueList)) {
7018
                    $sessionFieldValueListBySession = [];
7019
                    foreach ($sessionFieldValueList as $key => $sessionFieldValue) {
7020
                        // Create an array to index ids to session id
7021
                        $sessionFieldValueListBySession[$sessionFieldValue['item_id']][] = $key;
7022
                    }
7023
                }
7024
                // Query used to find course-coaches from sessions
7025
                $sql = "SELECT
7026
                            scu.session_id,
7027
                            c.id AS course_id,
7028
                            c.code AS course_code,
7029
                            c.title AS course_title,
7030
                            u.username AS coach_username,
7031
                            u.firstname AS coach_firstname,
7032
                            u.lastname AS coach_lastname
7033
                        FROM $courseTable c
7034
                        INNER JOIN $sessionCourseUserTable scu ON c.id = scu.c_id
7035
                        INNER JOIN $userTable u ON scu.user_id = u.user_id
7036
                        WHERE scu.status = 2 AND scu.session_id IN $sessionIdsString
7037
                        ORDER BY scu.session_id ASC ";
7038
                $res = Database::query($sql);
7039
                $sessionCourseList = Database::store_result($res, 'ASSOC');
7040
                // Check if course list had result
7041
                if (!empty($sessionCourseList)) {
7042
                    foreach ($sessionCourseList as $key => $sessionCourse) {
7043
                        // Create an array to index ids to session_id
7044
                        $sessionCourseListBySession[$sessionCourse['session_id']][] = $key;
7045
                    }
7046
                }
7047
                // Join lists
7048
                if (is_array($sessionList)) {
7049
                    foreach ($sessionList as $id => &$row) {
7050
                        if (
7051
                            !empty($sessionFieldValueListBySession) &&
7052
                            is_array($sessionFieldValueListBySession[$id])
7053
                        ) {
7054
                            // If have an index array for session extra fields, use it to join arrays
7055
                            foreach ($sessionFieldValueListBySession[$id] as $key) {
7056
                                $row['extra'][$key] = [
7057
                                    'field_name' => $sessionFieldList[$sessionFieldValueList[$key]['field_id']]['variable'],
7058
                                    'value' => $sessionFieldValueList[$key]['value'],
7059
                                ];
7060
                            }
7061
                        }
7062
                        if (
7063
                            !empty($sessionCourseListBySession) &&
7064
                            is_array($sessionCourseListBySession[$id])
7065
                        ) {
7066
                            // If have an index array for session course coach, use it to join arrays
7067
                            foreach ($sessionCourseListBySession[$id] as $key) {
7068
                                $row['course'][$key] = [
7069
                                    'course_id' => $sessionCourseList[$key]['course_id'],
7070
                                    'course_code' => $sessionCourseList[$key]['course_code'],
7071
                                    'course_title' => $sessionCourseList[$key]['course_title'],
7072
                                    'coach_username' => $sessionCourseList[$key]['coach_username'],
7073
                                    'coach_firstname' => $sessionCourseList[$key]['coach_firstname'],
7074
                                    'coach_lastname' => $sessionCourseList[$key]['coach_lastname'],
7075
                                ];
7076
                            }
7077
                        }
7078
                    }
7079
                }
7080
7081
                return $sessionList;
7082
            } else {
7083
                // Not found result, update error message
7084
                $errorResult['errorMessage'] = 'Not found any session for session category id '.$sessionCategoryId;
7085
            }
7086
        }
7087
7088
        return $errorResult;
7089
    }
7090
7091
    /**
7092
     * Return session description from session id
7093
     * @param int $sessionId
7094
     * @return string
7095
     */
7096
    public static function getDescriptionFromSessionId($sessionId)
7097
    {
7098
        // Init variables
7099
        $sessionId = intval($sessionId);
7100
        $description = '';
7101
        // Check if session id is valid
7102
        if ($sessionId > 0) {
7103
            // Select query from session id
7104
            $rows = Database::select(
7105
                'description',
7106
                Database::get_main_table(TABLE_MAIN_SESSION),
7107
                [
7108
                    'where' => [
7109
                        'id = ?' => $sessionId,
7110
                    ],
7111
                ]
7112
            );
7113
7114
            // Check if select query result is not empty
7115
            if (!empty($rows)) {
7116
                // Get session description
7117
                $description = $rows[0]['description'];
7118
            }
7119
        }
7120
7121
        return $description;
7122
    }
7123
7124
    /**
7125
     * Get a session list filtered by name, description or any of the given extra fields
7126
     * @param string $term The term to search
7127
     * @param array $extraFieldsToInclude Extra fields to include in the session data
7128
     * @return array The list
7129
     */
7130
    public static function searchSession($term, $extraFieldsToInclude = [])
7131
    {
7132
        $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
7133
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7134
        $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7135
        $term = Database::escape_string($term);
7136
        $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
7137
        if (is_array($extraFieldsToInclude) && count($extraFieldsToInclude) > 0) {
7138
            $resultData = Database::select('*', $sTable, [
7139
                'where' => [
7140
                    "name LIKE %?% " => $term,
7141
                    " OR description LIKE %?% " => $term,
7142
                    " OR id IN (
7143
                    SELECT item_id
7144
                    FROM $sfvTable v INNER JOIN $extraFieldTable e
7145
                    ON (v.field_id = e.id)
7146
                    WHERE value LIKE %?% AND extra_field_type = $extraFieldType
7147
                ) " => $term,
7148
                ],
7149
            ]);
7150
        } else {
7151
            $resultData = Database::select('*', $sTable, [
7152
                'where' => [
7153
                    "name LIKE %?% " => $term,
7154
                    "OR description LIKE %?% " => $term,
7155
                ],
7156
            ]);
7157
7158
            return $resultData;
7159
        }
7160
7161
        foreach ($resultData as $id => &$session) {
7162
            $session['extra'] = self::getFilteredExtraFields($id, $extraFieldsToInclude);
7163
        }
7164
7165
        return $resultData;
7166
    }
7167
7168
    /**
7169
     * @param int $sessionId
7170
     * @param array $extraFieldsToInclude
7171
     * @return array
7172
     */
7173
    public static function getFilteredExtraFields($sessionId, $extraFieldsToInclude = [])
7174
    {
7175
        $extraData = [];
7176
        $variables = [];
7177
        $variablePlaceHolders = [];
7178
7179
        foreach ($extraFieldsToInclude as $sessionExtraField) {
7180
            $variablePlaceHolders[] = "?";
7181
            $variables[] = Database::escape_string($sessionExtraField);
7182
        }
7183
7184
        $sessionExtraField = new ExtraFieldModel('session');
7185
        $fieldList = $sessionExtraField->get_all([
7186
            "variable IN ( ".implode(", ", $variablePlaceHolders)." ) " => $variables,
7187
        ]);
7188
7189
        $fields = [];
7190
7191
        // Index session fields
7192
        foreach ($fieldList as $field) {
7193
            $fields[$field['id']] = $field['variable'];
7194
        }
7195
7196
        // Get session field values
7197
        $extra = new ExtraFieldValue('session');
7198
        $sessionFieldValueList = $extra->get_all(
7199
            [
7200
                "field_id IN ( ".implode(", ", $variablePlaceHolders)." )" => array_keys($fields),
7201
            ]
7202
        );
7203
7204
        foreach ($sessionFieldValueList as $sessionFieldValue) {
7205
            // Match session field values to session
7206
            if ($sessionFieldValue['item_id'] != $sessionId) {
7207
                continue;
7208
            }
7209
7210
            // Check if session field value is set in session field list
7211
            if (!isset($fields[$sessionFieldValue['field_id']])) {
7212
                continue;
7213
            }
7214
7215
            $extrafieldVariable = $fields[$sessionFieldValue['field_id']];
7216
            $extrafieldValue = $sessionFieldValue['value'];
7217
7218
            $extraData[] = [
7219
                'variable' => $extrafieldVariable,
7220
                'value' => $extrafieldValue,
7221
            ];
7222
        }
7223
7224
        return $extraData;
7225
    }
7226
7227
    /**
7228
     * @param int $sessionId
7229
     *
7230
     * @return bool
7231
     */
7232
    public static function isValidId($sessionId)
7233
    {
7234
        $sessionId = intval($sessionId);
7235
        if ($sessionId > 0) {
7236
            $rows = Database::select(
7237
                'id',
7238
                Database::get_main_table(TABLE_MAIN_SESSION),
7239
                ['where' => ['id = ?' => $sessionId]]
7240
            );
7241
            if (!empty($rows)) {
7242
                return true;
7243
            }
7244
        }
7245
7246
        return false;
7247
    }
7248
7249
    /**
7250
     * Get list of sessions based on users of a group for a group admin
7251
     * @param int $userId The user id
7252
     * @return array
7253
     */
7254
    public static function getSessionsFollowedForGroupAdmin($userId)
7255
    {
7256
        $sessionList = [];
7257
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
7258
        $sessionUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7259
        $userGroup = new UserGroup();
7260
        $userIdList = $userGroup->getGroupUsersByUser($userId);
7261
7262
        if (empty($userIdList)) {
7263
            return [];
7264
        }
7265
7266
        $sql = "SELECT DISTINCT s.*
7267
                FROM $sessionTable s
7268
                INNER JOIN $sessionUserTable sru 
7269
                ON s.id = sru.id_session
7270
                WHERE
7271
                    (sru.id_user IN (".implode(', ', $userIdList).")
7272
                    AND sru.relation_type = 0
7273
                )";
7274
7275
        if (api_is_multiple_url_enabled()) {
7276
            $sessionAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
7277
            $accessUrlId = api_get_current_access_url_id();
7278
7279
            if ($accessUrlId != -1) {
7280
                $sql = "SELECT DISTINCT s.*
7281
                        FROM $sessionTable s
7282
                        INNER JOIN $sessionUserTable sru ON s.id = sru.id_session
7283
                        INNER JOIN $sessionAccessUrlTable srau ON s.id = srau.session_id
7284
                        WHERE
7285
                            srau.access_url_id = $accessUrlId
7286
                            AND (
7287
                                sru.id_user IN (".implode(', ', $userIdList).")
7288
                                AND sru.relation_type = 0
7289
                            )";
7290
            }
7291
        }
7292
7293
        $result = Database::query($sql);
7294
7295
        while ($row = Database::fetch_assoc($result)) {
7296
            $sessionList[] = $row;
7297
        }
7298
7299
        return $sessionList;
7300
    }
7301
7302
    /**
7303
     * @param array $sessionInfo
7304
     * @return string
7305
     */
7306
    public static function getSessionVisibility($sessionInfo)
7307
    {
7308
        switch ($sessionInfo['visibility']) {
7309
            case 1:
7310
                return get_lang('ReadOnly');
7311
            case 2:
7312
               return get_lang('Visible');
7313
            case 3:
7314
                return api_ucfirst(get_lang('Invisible'));
7315
        }
7316
    }
7317
7318
    /**
7319
     * Converts "start date" and "end date" to "From start date to end date" string
7320
     * @param string $startDate
7321
     * @param string $endDate
7322
     * @param bool $showTime
7323
     * @param bool $dateHuman
7324
     *
7325
     * @return string
7326
     */
7327
    private static function convertSessionDateToString($startDate, $endDate, $showTime, $dateHuman)
7328
    {
7329
        // api_get_local_time returns empty if date is invalid like 0000-00-00 00:00:00
7330
        $startDateToLocal = api_get_local_time(
7331
            $startDate,
7332
            null,
7333
            null,
7334
            true,
7335
            $showTime,
7336
            $dateHuman
7337
        );
7338
        $endDateToLocal = api_get_local_time(
7339
            $endDate,
7340
            null,
7341
            null,
7342
            true,
7343
            $showTime,
7344
            $dateHuman
7345
        );
7346
7347
        $result = '';
7348
        if (!empty($startDateToLocal) && !empty($endDateToLocal)) {
7349
            $result = sprintf(
7350
                get_lang('FromDateXToDateY'),
7351
                api_format_date($startDateToLocal, DATE_TIME_FORMAT_LONG_24H),
7352
                api_format_date($endDateToLocal, DATE_TIME_FORMAT_LONG_24H)
7353
            );
7354
        } else {
7355
            if (!empty($startDateToLocal)) {
7356
                $result = get_lang('From').' '.api_format_date($startDateToLocal, DATE_TIME_FORMAT_LONG_24H);
7357
            }
7358
            if (!empty($endDateToLocal)) {
7359
                $result = get_lang('Until').' '.api_format_date($endDateToLocal, DATE_TIME_FORMAT_LONG_24H);
7360
            }
7361
        }
7362
        if (empty($result)) {
7363
            $result = get_lang('NoTimeLimits');
7364
        }
7365
7366
        return $result;
7367
    }
7368
7369
    /**
7370
     * Returns a human readable string
7371
     * @params array $sessionInfo An array with all the session dates
7372
     * @param bool $showTime
7373
     *
7374
     * @return array
7375
     */
7376
    public static function parseSessionDates($sessionInfo, $showTime = false)
7377
    {
7378
        $displayDates = self::convertSessionDateToString(
7379
            $sessionInfo['display_start_date'],
7380
            $sessionInfo['display_end_date'],
7381
            $showTime,
7382
            true
7383
        );
7384
        $accessDates = self::convertSessionDateToString(
7385
            $sessionInfo['access_start_date'],
7386
            $sessionInfo['access_end_date'],
7387
            $showTime,
7388
            true
7389
        );
7390
7391
        $coachDates = self::convertSessionDateToString(
7392
            $sessionInfo['coach_access_start_date'],
7393
            $sessionInfo['coach_access_end_date'],
7394
            $showTime,
7395
            true
7396
        );
7397
7398
        $result = [
7399
            'access' => $accessDates,
7400
            'display' => $displayDates,
7401
            'coach' => $coachDates,
7402
        ];
7403
7404
        return $result;
7405
    }
7406
7407
    /**
7408
     * @param FormValidator $form
7409
     * @param array $sessionInfo Optional
7410
     * @return array
7411
     */
7412
    public static function setForm(FormValidator $form, array $sessionInfo = [])
7413
    {
7414
        $sessionId = 0;
7415
        $coachInfo = [];
7416
7417
        if (!empty($sessionInfo)) {
7418
            $sessionId = intval($sessionInfo['id']);
7419
            $coachInfo = api_get_user_info($sessionInfo['id_coach']);
7420
        };
7421
7422
        $categoriesList = self::get_all_session_category();
7423
        $userInfo = api_get_user_info();
7424
7425
        $categoriesOptions = [
7426
            '0' => get_lang('None'),
7427
        ];
7428
7429
        if ($categoriesList != false) {
7430
            foreach ($categoriesList as $categoryItem) {
7431
                $categoriesOptions[$categoryItem['id']] = $categoryItem['name'];
7432
            }
7433
        }
7434
7435
        // Database Table Definitions
7436
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
7437
7438
        $form->addText(
7439
            'name',
7440
            get_lang('SessionName'),
7441
            true,
7442
            ['maxlength' => 150, 'aria-label' => get_lang('SessionName')]
7443
        );
7444
        $form->addRule('name', get_lang('SessionNameAlreadyExists'), 'callback', 'check_session_name');
7445
7446
        if (!api_is_platform_admin() && api_is_teacher()) {
7447
            $form->addElement(
7448
                'select',
7449
                'coach_username',
7450
                get_lang('CoachName'),
7451
                [api_get_user_id() => $userInfo['complete_name']],
7452
                [
7453
                    'id' => 'coach_username',
7454
                    'style' => 'width:370px;',
7455
                ]
7456
            );
7457
        } else {
7458
            $sql = "SELECT COUNT(1) FROM $tbl_user WHERE status = 1";
7459
            $rs = Database::query($sql);
7460
            $countUsers = Database::result($rs, 0, 0);
7461
7462
            if (intval($countUsers) < 50) {
7463
                $orderClause = "ORDER BY ";
7464
                $orderClause .= api_sort_by_first_name() ? "firstname, lastname, username" : "lastname, firstname, username";
7465
7466
                $sql = "SELECT user_id, lastname, firstname, username
7467
                        FROM $tbl_user
7468
                        WHERE status = '1' ".
7469
                        $orderClause;
7470
7471
                if (api_is_multiple_url_enabled()) {
7472
                    $userRelAccessUrlTable = Database::get_main_table(
7473
                        TABLE_MAIN_ACCESS_URL_REL_USER
7474
                    );
7475
                    $accessUrlId = api_get_current_access_url_id();
7476
7477
                    if ($accessUrlId != -1) {
7478
                        $sql = "SELECT user.user_id, username, lastname, firstname
7479
                        FROM $tbl_user user
7480
                        INNER JOIN $userRelAccessUrlTable url_user
7481
                        ON (url_user.user_id = user.user_id)
7482
                        WHERE
7483
                            access_url_id = $accessUrlId AND
7484
                            status = 1 "
7485
                            .$orderClause;
7486
                    }
7487
                }
7488
7489
                $result = Database::query($sql);
7490
                $coachesList = Database::store_result($result);
7491
7492
                $coachesOptions = [];
7493
                foreach ($coachesList as $coachItem) {
7494
                    $coachesOptions[$coachItem['user_id']] =
7495
                        api_get_person_name($coachItem['firstname'], $coachItem['lastname']).' ('.$coachItem['username'].')';
7496
                }
7497
7498
                $form->addElement(
7499
                    'select',
7500
                    'coach_username',
7501
                    get_lang('CoachName'),
7502
                    $coachesOptions,
7503
                    [
7504
                        'id' => 'coach_username',
7505
                        'style' => 'width:370px;'
7506
                    ]
7507
                );
7508
            } else {
7509
                $form->addElement(
7510
                    'select_ajax',
7511
                    'coach_username',
7512
                    get_lang('CoachName'),
7513
                    $coachInfo ? [$coachInfo['id'] => $coachInfo['complete_name_with_username']] : [],
7514
                    [
7515
                        'url' => api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=search_general_coach',
7516
                        'width' => '100%',
7517
                        'id' => 'coach_username'
7518
                    ]
7519
                );
7520
            }
7521
        }
7522
7523
        $form->addRule('coach_username', get_lang('ThisFieldIsRequired'), 'required');
7524
        $form->addHtml('<div id="ajax_list_coachs"></div>');
7525
7526
        $form->addButtonAdvancedSettings('advanced_params');
7527
        $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
7528
7529
        if (empty($sessionId)) {
7530
            $sessions = SessionManager::get_sessions_admin();
7531
            $sessionList = [];
7532
            $sessionList[] = '';
7533
            foreach ($sessions as $session) {
7534
                $sessionList[$session['id']] = $session['name'];
7535
            }
7536
7537
            $form->addSelect(
7538
                'session_template',
7539
                get_lang('SessionTemplate'),
7540
                $sessionList,
7541
                ['id' => 'system_template']
7542
            );
7543
        }
7544
7545
        $form->addSelect(
7546
            'session_category',
7547
            get_lang('SessionCategory'),
7548
            $categoriesOptions,
7549
            [
7550
                'id' => 'session_category',
7551
            ]
7552
        );
7553
7554
        $form->addHtmlEditor(
7555
            'description',
7556
            get_lang('Description'),
7557
            false,
7558
            false,
7559
            [
7560
                'ToolbarSet' => 'Minimal',
7561
            ]
7562
        );
7563
7564
        $form->addElement('checkbox', 'show_description', null, get_lang('ShowDescription'));
7565
7566
        $visibilityGroup = [];
7567
        $visibilityGroup[] = $form->createElement('select', 'session_visibility', null, [
7568
            SESSION_VISIBLE_READ_ONLY => get_lang('SessionReadOnly'),
7569
            SESSION_VISIBLE => get_lang('SessionAccessible'),
7570
            SESSION_INVISIBLE => api_ucfirst(get_lang('SessionNotAccessible')),
7571
        ]);
7572
        $form->addGroup(
7573
            $visibilityGroup,
7574
            'visibility_group',
7575
            get_lang('SessionVisibility'),
7576
            null,
7577
            false
7578
        );
7579
7580
        $options = [
7581
            0 => get_lang('ByDuration'),
7582
            1 => get_lang('ByDates'),
7583
        ];
7584
7585
        $form->addSelect('access', get_lang('Access'), $options, [
7586
            'onchange' => 'accessSwitcher()',
7587
            'id' => 'access',
7588
        ]);
7589
7590
        $form->addHtml('<div id="duration" style="display:none">');
7591
7592
        $form->addElement(
7593
            'number',
7594
            'duration',
7595
            [
7596
                get_lang('SessionDurationTitle'),
7597
                get_lang('SessionDurationDescription'),
7598
            ],
7599
            [
7600
                'maxlength' => 50,
7601
            ]
7602
        );
7603
7604
        $form->addHtml('</div>');
7605
        $form->addHtml('<div id="date_fields" style="display:none">');
7606
7607
        // Dates
7608
        $form->addDateTimePicker(
7609
            'access_start_date',
7610
            [get_lang('SessionStartDate'), get_lang('SessionStartDateComment')],
7611
            ['id' => 'access_start_date']
7612
        );
7613
7614
        $form->addDateTimePicker(
7615
            'access_end_date',
7616
            [get_lang('SessionEndDate'), get_lang('SessionEndDateComment')],
7617
            ['id' => 'access_end_date']
7618
        );
7619
7620
        $form->addRule(
7621
            ['access_start_date', 'access_end_date'],
7622
            get_lang('StartDateMustBeBeforeTheEndDate'),
7623
            'compare_datetime_text',
7624
            '< allow_empty'
7625
        );
7626
7627
        $form->addDateTimePicker(
7628
            'display_start_date',
7629
            [
7630
                get_lang('SessionDisplayStartDate'),
7631
                get_lang('SessionDisplayStartDateComment'),
7632
            ],
7633
            ['id' => 'display_start_date']
7634
        );
7635
7636
        $form->addDateTimePicker(
7637
            'display_end_date',
7638
            [
7639
                get_lang('SessionDisplayEndDate'),
7640
                get_lang('SessionDisplayEndDateComment'),
7641
            ],
7642
            ['id' => 'display_end_date']
7643
        );
7644
7645
        $form->addRule(
7646
            ['display_start_date', 'display_end_date'],
7647
            get_lang('StartDateMustBeBeforeTheEndDate'),
7648
            'compare_datetime_text',
7649
            '< allow_empty'
7650
        );
7651
7652
        $form->addDateTimePicker(
7653
            'coach_access_start_date',
7654
            [
7655
                get_lang('SessionCoachStartDate'),
7656
                get_lang('SessionCoachStartDateComment'),
7657
            ],
7658
            ['id' => 'coach_access_start_date']
7659
        );
7660
7661
        $form->addDateTimePicker(
7662
            'coach_access_end_date',
7663
            [
7664
                get_lang('SessionCoachEndDate'),
7665
                get_lang('SessionCoachEndDateComment'),
7666
            ],
7667
            ['id' => 'coach_access_end_date']
7668
        );
7669
7670
        $form->addRule(
7671
            ['coach_access_start_date', 'coach_access_end_date'],
7672
            get_lang('StartDateMustBeBeforeTheEndDate'),
7673
            'compare_datetime_text',
7674
            '< allow_empty'
7675
        );
7676
7677
        $form->addElement('html', '</div>');
7678
7679
        $form->addCheckBox(
7680
            'send_subscription_notification',
7681
            [
7682
                get_lang('SendSubscriptionNotification'),
7683
                get_lang('SendAnEmailWhenAUserBeingSubscribed'),
7684
            ]
7685
        );
7686
7687
        // Extra fields
7688
        $extra_field = new ExtraFieldModel('session');
7689
        $extra = $extra_field->addElements($form, $sessionId);
7690
7691
        $form->addElement('html', '</div>');
7692
7693
        $js = $extra['jquery_ready_content'];
7694
7695
        return ['js' => $js];
7696
    }
7697
7698
    /**
7699
     * Gets the number of rows in the session table filtered through the given
7700
     * array of parameters
7701
     * @param array Array of options/filters/keys
7702
     * @return integer The number of rows, or false on wrong param
7703
     * @assert ('a') === false
7704
     */
7705
    public static function get_count_admin_complete($options = [])
7706
    {
7707
        if (!is_array($options)) {
7708
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type integer.
Loading history...
7709
        }
7710
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
7711
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
7712
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
7713
        $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
7714
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
7715
        $tbl_session_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7716
        $tbl_session_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
7717
7718
        $where = 'WHERE 1 = 1 ';
7719
        $user_id = api_get_user_id();
7720
7721
        if (api_is_session_admin() &&
7722
            api_get_setting('allow_session_admins_to_see_all_sessions') == 'false'
7723
        ) {
7724
            $where .= " WHERE s.session_admin_id = $user_id ";
7725
        }
7726
7727
        $extraFieldTables = '';
7728
        if (!empty($options['where'])) {
7729
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
7730
            $options['where'] = str_replace("( session_active = '0' )", '1=1', $options['where']);
7731
7732
            $options['where'] = str_replace(
7733
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
7734
                [') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 "],
7735
                $options['where']
7736
            );
7737
7738
            $options['where'] = str_replace(
7739
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
7740
                [') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "],
7741
                $options['where']
7742
            );
7743
7744
            if (!empty($options['extra'])) {
7745
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
7746
                $options['where'] = str_replace('AND', 'OR', $options['where']);
7747
7748
                foreach ($options['extra'] as $extra) {
7749
                    $options['where'] = str_replace($extra['field'], 'fv.field_id = '.$extra['id'].' AND fvo.option_value', $options['where']);
7750
                    $extraFieldTables = "$tbl_session_field_values fv, $tbl_session_field_options fvo, ";
7751
                }
7752
            }
7753
            $where .= ' AND '.$options['where'];
7754
        }
7755
7756
        $today = api_get_utc_datetime();
7757
        $query_rows = "SELECT count(*) as total_rows, c.title as course_title, s.name,
7758
                        IF (
7759
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
7760
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
7761
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
7762
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
7763
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
7764
                        , 1, 0) as session_active
7765
                       FROM $extraFieldTables $tbl_session s
7766
                       LEFT JOIN  $tbl_session_category sc
7767
                       ON s.session_category_id = sc.id
7768
                       INNER JOIN $tbl_user u
7769
                       ON s.id_coach = u.user_id
7770
                       INNER JOIN $sessionCourseUserTable scu
7771
                       ON s.id = scu.session_id
7772
                       INNER JOIN $courseTable c
7773
                       ON c.id = scu.c_id
7774
                       $where ";
7775
7776
        if (api_is_multiple_url_enabled()) {
7777
            $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
7778
            $access_url_id = api_get_current_access_url_id();
7779
            if ($access_url_id != -1) {
7780
                $where .= " AND ar.access_url_id = $access_url_id ";
7781
7782
                $query_rows = "SELECT count(*) as total_rows
7783
                               FROM $tbl_session s
7784
                               LEFT JOIN  $tbl_session_category sc
7785
                               ON s.session_category_id = sc.id
7786
                               INNER JOIN $tbl_user u
7787
                               ON s.id_coach = u.user_id
7788
                               INNER JOIN $table_access_url_rel_session ar
7789
                               ON ar.session_id = s.id $where ";
7790
            }
7791
        }
7792
7793
        $result = Database::query($query_rows);
7794
        $num = 0;
7795
        if (Database::num_rows($result)) {
7796
            $rows = Database::fetch_array($result);
7797
            $num = $rows['total_rows'];
7798
        }
7799
7800
        return $num;
7801
    }
7802
7803
    /**
7804
     * @param string $list_type
7805
     * @param array $extraFields
7806
     * @return array
7807
     */
7808
    public static function getGridColumns(
7809
        $list_type = 'simple',
7810
        $extraFields = []
7811
    ) {
7812
        $showCount = api_get_configuration_value('session_list_show_count_users');
7813
        // Column config
7814
        $operators = ['cn', 'nc'];
7815
        $date_operators = ['gt', 'ge', 'lt', 'le'];
7816
7817
        switch ($list_type) {
7818
            case 'simple':
7819
                $columns = [
7820
                    '#',
7821
                    get_lang('Name'),
7822
                    get_lang('Category'),
7823
                    get_lang('SessionDisplayStartDate'),
7824
                    get_lang('SessionDisplayEndDate'),
7825
                    //get_lang('Coach'),
7826
                    //get_lang('Status'),
7827
                    //get_lang('CourseTitle'),
7828
                    get_lang('Visibility'),
7829
                ];
7830
7831
                $column_model = [
7832
                    [
7833
                        'name' => 'id',
7834
                        'index' => 's.id',
7835
                        'width' => '160',
7836
                        'width' => '160',
7837
                        'hidden' => 'true',
7838
                    ],
7839
                    [
7840
                        'name' => 'name',
7841
                        'index' => 's.name',
7842
                        'width' => '160',
7843
                        'align' => 'left',
7844
                        'search' => 'true',
7845
                        'searchoptions' => ['sopt' => $operators],
7846
                    ],
7847
                    [
7848
                        'name' => 'category_name',
7849
                        'index' => 'category_name',
7850
                        'width' => '40',
7851
                        'align' => 'left',
7852
                        'search' => 'true',
7853
                        'searchoptions' => ['sopt' => $operators],
7854
                    ],
7855
                    [
7856
                        'name' => 'display_start_date',
7857
                        'index' => 'display_start_date',
7858
                        'width' => '50',
7859
                        'align' => 'left',
7860
                        'search' => 'true',
7861
                        'searchoptions' => [
7862
                            'dataInit' => 'date_pick_today',
7863
                            'sopt' => $date_operators,
7864
                        ],
7865
                    ],
7866
                    [
7867
                        'name' => 'display_end_date',
7868
                        'index' => 'display_end_date',
7869
                        'width' => '50',
7870
                        'align' => 'left',
7871
                        'search' => 'true',
7872
                        'searchoptions' => [
7873
                            'dataInit' => 'date_pick_one_month',
7874
                            'sopt' => $date_operators,
7875
                        ],
7876
                    ],
7877
                    [
7878
                        'name' => 'visibility',
7879
                        'index' => 'visibility',
7880
                        'width' => '40',
7881
                        'align' => 'left',
7882
                        'search' => 'false',
7883
                    ],
7884
                ];
7885
7886
                if ($showCount) {
7887
                    $columns[] = get_lang('Users');
7888
                    $column_model[] = [
7889
                        'name' => 'users',
7890
                        'index' => 'users',
7891
                        'width' => '20',
7892
                        'align' => 'left',
7893
                        'search' => 'false',
7894
                    ];
7895
                }
7896
                break;
7897
            case 'complete':
7898
                $columns = [
7899
                    get_lang('Name'),
7900
                    get_lang('SessionDisplayStartDate'),
7901
                    get_lang('SessionDisplayEndDate'),
7902
                    get_lang('Coach'),
7903
                    get_lang('Status'),
7904
                    get_lang('Visibility'),
7905
                    get_lang('CourseTitle'),
7906
                ];
7907
                $column_model = [
7908
                    ['name'=>'name', 'index'=>'s.name', 'width'=>'200', 'align'=>'left', 'search' => 'true', 'searchoptions' => ['sopt' => $operators]],
7909
                    ['name'=>'display_start_date', 'index'=>'display_start_date', 'width'=>'70', 'align'=>'left', 'search' => 'true', 'searchoptions' => ['dataInit' => 'date_pick_today', 'sopt' => $date_operators]],
7910
                    ['name'=>'display_end_date', 'index'=>'display_end_date', 'width'=>'70', 'align'=>'left', 'search' => 'true', 'searchoptions' => ['dataInit' => 'date_pick_one_month', 'sopt' => $date_operators]],
7911
                    ['name'=>'coach_name', 'index'=>'coach_name', 'width'=>'70', 'align'=>'left', 'search' => 'false', 'searchoptions' => ['sopt' => $operators]],
7912
                    ['name'=>'session_active', 'index'=>'session_active', 'width'=>'25', 'align'=>'left', 'search' => 'true', 'stype'=>'select',
7913
                        // for the bottom bar
7914
                        'searchoptions' => [
7915
                            'defaultValue'  => '1',
7916
                            'value'         => '1:'.get_lang('Active').';0:'.get_lang('Inactive')],
7917
                        // for the top bar
7918
                        'editoptions' => ['value' => '" ":'.get_lang('All').';1:'.get_lang('Active').';0:'.get_lang('Inactive')],
7919
                    ],
7920
                    ['name'=>'visibility', 'index'=>'visibility', 'width'=>'40', 'align'=>'left', 'search' => 'false'],
7921
                    ['name'=>'course_title', 'index'=>'course_title', 'width'=>'50', 'hidden' => 'true', 'search' => 'true', 'searchoptions' => ['searchhidden' =>'true', 'sopt' => $operators]],
7922
                ];
7923
                break;
7924
        }
7925
7926
        if (!empty($extraFields)) {
7927
            foreach ($extraFields as $field) {
7928
                $columns[] = $field['display_text'];
7929
                $column_model[] = [
7930
                    'name' => $field['variable'],
7931
                    'index' => $field['variable'],
7932
                    'width' => '80',
7933
                    'align' => 'center',
7934
                    'search' => 'false'
7935
                ];
7936
            }
7937
        }
7938
7939
        // Inject extra session fields
7940
        $session_field = new ExtraFieldModel('session');
7941
        $rules = $session_field->getRules($columns, $column_model);
7942
7943
        $column_model[] = [
7944
            'name' => 'actions',
7945
            'index' => 'actions',
7946
            'width' => '80',
7947
            'align' => 'left',
7948
            'formatter' => 'action_formatter',
7949
            'sortable' => 'false',
7950
            'search' => 'false',
7951
        ];
7952
        $columns[] = get_lang('Actions');
7953
7954
        foreach ($column_model as $col_model) {
7955
            $simple_column_name[] = $col_model['name'];
7956
        }
7957
7958
        $return_array = [
7959
            'columns' => $columns,
7960
            'column_model' => $column_model,
7961
            'rules' => $rules,
7962
            'simple_column_name' => $simple_column_name,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $simple_column_name seems to be defined by a foreach iteration on line 7954. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
7963
        ];
7964
7965
        return $return_array;
7966
    }
7967
7968
    /**
7969
     * Converts all dates sent through the param array (given form) to correct dates with timezones
7970
     * @param array The dates The same array, with times converted
7971
     * @param boolean $applyFormat Whether apply the DATE_TIME_FORMAT_SHORT format for sessions
7972
     * @return array The same array, with times converted
7973
     */
7974
    public static function convert_dates_to_local($params, $applyFormat = false)
7975
    {
7976
        if (!is_array($params)) {
7977
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type array.
Loading history...
7978
        }
7979
        $params['display_start_date'] = api_get_local_time($params['display_start_date'], null, null, true);
7980
        $params['display_end_date'] = api_get_local_time($params['display_end_date'], null, null, true);
7981
7982
        $params['access_start_date'] = api_get_local_time($params['access_start_date'], null, null, true);
7983
        $params['access_end_date'] = api_get_local_time($params['access_end_date'], null, null, true);
7984
7985
        $params['coach_access_start_date'] = isset($params['coach_access_start_date']) ? api_get_local_time($params['coach_access_start_date'], null, null, true) : null;
7986
        $params['coach_access_end_date'] = isset($params['coach_access_end_date']) ? api_get_local_time($params['coach_access_end_date'], null, null, true) : null;
7987
7988
        if ($applyFormat) {
7989
            if (isset($params['display_start_date'])) {
7990
                $params['display_start_date'] = api_format_date($params['display_start_date'], DATE_TIME_FORMAT_SHORT);
7991
            }
7992
7993
            if (isset($params['display_end_date'])) {
7994
                $params['display_end_date'] = api_format_date($params['display_end_date'], DATE_TIME_FORMAT_SHORT);
7995
            }
7996
7997
            if (isset($params['access_start_date'])) {
7998
                $params[''] = api_format_date($params['access_start_date'], DATE_TIME_FORMAT_SHORT);
7999
            }
8000
8001
            if (isset($params['access_end_date'])) {
8002
                $params['access_end_date'] = api_format_date($params['access_end_date'], DATE_TIME_FORMAT_SHORT);
8003
            }
8004
8005
            if (isset($params['coach_access_start_date'])) {
8006
                $params['coach_access_start_date'] = api_format_date($params['coach_access_start_date'], DATE_TIME_FORMAT_SHORT);
8007
            }
8008
8009
            if (isset($params['coach_access_end_date'])) {
8010
                $params['coach_access_end_date'] = api_format_date($params['coach_access_end_date'], DATE_TIME_FORMAT_SHORT);
8011
            }
8012
        }
8013
8014
        return $params;
8015
    }
8016
8017
    /**
8018
     * Gets the admin session list callback of the session/session_list.php
8019
     * page with all user/details in the right fomat
8020
     * @param array $options
8021
     * @return array Array of rows results
8022
     * @asset ('a') === false
8023
     */
8024
    public static function get_sessions_admin_complete($options = [])
8025
    {
8026
        if (!is_array($options)) {
8027
            return false;
8028
        }
8029
8030
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
8031
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
8032
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
8033
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
8034
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
8035
8036
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
8037
        $tbl_session_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
8038
        $tbl_session_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
8039
8040
        $where = 'WHERE 1 = 1 ';
8041
        $user_id = api_get_user_id();
8042
8043
        if (!api_is_platform_admin()) {
8044
            if (api_is_session_admin() &&
8045
                api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
8046
            ) {
8047
                $where .= " AND s.session_admin_id = $user_id ";
8048
            }
8049
        }
8050
8051
        $coach_name = " CONCAT(u.lastname , ' ', u.firstname) as coach_name ";
8052
        if (api_is_western_name_order()) {
8053
            $coach_name = " CONCAT(u.firstname, ' ', u.lastname) as coach_name ";
8054
        }
8055
8056
        $today = api_get_utc_datetime();
8057
        $inject_extra_fields = null;
8058
        $extra_fields = [];
8059
        $extra_fields_info = [];
8060
8061
        //for now only sessions
8062
        $extra_field = new ExtraFieldModel('session');
8063
        $double_fields = [];
8064
        $extra_field_option = new ExtraFieldOption('session');
8065
8066
        if (isset($options['extra'])) {
8067
            $extra_fields = $options['extra'];
8068
            if (!empty($extra_fields)) {
8069
                foreach ($extra_fields as $extra) {
8070
                    $inject_extra_fields .= " IF (fv.field_id = {$extra['id']}, fvo.option_display_text, NULL ) as {$extra['field']} , ";
8071
                    if (isset($extra_fields_info[$extra['id']])) {
8072
                        $info = $extra_fields_info[$extra['id']];
8073
                    } else {
8074
                        $info = $extra_field->get($extra['id']);
8075
                        $extra_fields_info[$extra['id']] = $info;
8076
                    }
8077
8078
                    if ($info['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) {
0 ignored issues
show
Bug introduced by
The constant Chamilo\CoreBundle\Entit...IELD_TYPE_DOUBLE_SELECT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
8079
                        $double_fields[$info['id']] = $info;
8080
                    }
8081
                }
8082
            }
8083
        }
8084
8085
        $options_by_double = [];
8086
        foreach ($double_fields as $double) {
8087
            $my_options = $extra_field_option->get_field_options_by_field(
8088
                $double['id'],
8089
                true
8090
            );
8091
            $options_by_double['extra_'.$double['field_variable']] = $my_options;
8092
        }
8093
8094
        //sc.name as category_name,
8095
        $select = "
8096
                SELECT * FROM (
8097
                    SELECT DISTINCT
8098
                        IF (
8099
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
8100
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
8101
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
8102
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
8103
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
8104
                        , 1, 0) as session_active,
8105
                s.name,
8106
                s.nbr_courses,
8107
                s.nbr_users,
8108
                s.display_start_date,
8109
                s.display_end_date,
8110
                $coach_name,
8111
                access_start_date,
8112
                access_end_date,
8113
                s.visibility,
8114
                u.user_id,
8115
                $inject_extra_fields
8116
                c.title as course_title,
8117
                s.id ";
8118
8119
        if (!empty($options['where'])) {
8120
            if (!empty($options['extra'])) {
8121
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
8122
                $options['where'] = str_replace('AND', 'OR', $options['where']);
8123
                foreach ($options['extra'] as $extra) {
8124
                    $options['where'] = str_replace($extra['field'], 'fv.field_id = '.$extra['id'].' AND fvo.option_value', $options['where']);
8125
                }
8126
            }
8127
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
8128
            $options['where'] = str_replace("( session_active = '0' )", '1=1', $options['where']);
8129
            $options['where'] = str_replace(
8130
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
8131
                [') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 "],
8132
                $options['where']
8133
            );
8134
8135
            $options['where'] = str_replace(
8136
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
8137
                [') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "],
8138
                $options['where']
8139
            );
8140
8141
8142
            $where .= ' AND '.$options['where'];
8143
        }
8144
8145
        $limit = '';
8146
        if (!empty($options['limit'])) {
8147
            $limit = " LIMIT ".$options['limit'];
8148
        }
8149
8150
        $query = "$select FROM $tbl_session s
8151
                    LEFT JOIN $tbl_session_field_values fv
8152
                    ON (fv.item_id = s.id)
8153
                    LEFT JOIN $extraFieldTable f
8154
                    ON f.id = fv.field_id
8155
                    LEFT JOIN $tbl_session_field_options fvo
8156
                    ON (fv.field_id = fvo.field_id)
8157
                    LEFT JOIN $tbl_session_rel_course src
8158
                    ON (src.session_id = s.id)
8159
                    LEFT JOIN $tbl_course c
8160
                    ON (src.c_id = c.id)
8161
                    LEFT JOIN $tbl_session_category sc
8162
                    ON (s.session_category_id = sc.id)
8163
                    INNER JOIN $tbl_user u
8164
                    ON (s.id_coach = u.user_id) 
8165
                    $where
8166
                    $limit
8167
        ";
8168
8169
        if (api_is_multiple_url_enabled()) {
8170
            $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
8171
            $access_url_id = api_get_current_access_url_id();
8172
            if ($access_url_id != -1) {
8173
                $query = "$select
8174
                    FROM $tbl_session s
8175
                    LEFT JOIN $tbl_session_field_values fv 
8176
                    ON (fv.item_id = s.id)
8177
                    LEFT JOIN $tbl_session_field_options fvo 
8178
                    ON (fv.field_id = fvo.field_id)
8179
                    LEFT JOIN $tbl_session_rel_course src 
8180
                    ON (src.session_id = s.id)
8181
                    LEFT JOIN $tbl_course c 
8182
                    ON (src.c_id = c.id)
8183
                    LEFT JOIN $tbl_session_category sc 
8184
                    ON (s.session_category_id = sc.id)
8185
                    INNER JOIN $tbl_user u 
8186
                    ON (s.id_coach = u.user_id)
8187
                    INNER JOIN $table_access_url_rel_session ar 
8188
                    ON (ar.session_id = s.id AND ar.access_url_id = $access_url_id)
8189
                    $where
8190
                    $limit
8191
                ";
8192
            }
8193
        }
8194
8195
        $query .= ") AS session_table";
8196
8197
        if (!empty($options['order'])) {
8198
            $query .= " ORDER BY ".$options['order'];
8199
        }
8200
8201
        $result = Database::query($query);
8202
8203
        $acceptIcon = Display::return_icon(
8204
            'accept.png',
8205
            get_lang('Active'),
8206
            [],
8207
            ICON_SIZE_SMALL
8208
        );
8209
8210
        $errorIcon = Display::return_icon(
8211
            'error.png',
8212
            get_lang('Inactive'),
8213
            [],
8214
            ICON_SIZE_SMALL
8215
        );
8216
8217
        $formatted_sessions = [];
8218
        if (Database::num_rows($result)) {
8219
            $sessions = Database::store_result($result, 'ASSOC');
8220
            foreach ($sessions as $session) {
8221
                $session_id = $session['id'];
8222
                $session['name'] = Display::url($session['name'], "resume_session.php?id_session=".$session['id']);
8223
                $session['coach_name'] = Display::url($session['coach_name'], "user_information.php?user_id=".$session['user_id']);
8224
                if ($session['session_active'] == 1) {
8225
                    $session['session_active'] = $acceptIcon;
8226
                } else {
8227
                    $session['session_active'] = $errorIcon;
8228
                }
8229
8230
                $session = self::convert_dates_to_local($session);
8231
8232
                switch ($session['visibility']) {
8233
                    case SESSION_VISIBLE_READ_ONLY: //1
8234
                        $session['visibility'] = get_lang('ReadOnly');
8235
                        break;
8236
                    case SESSION_VISIBLE:           //2
8237
                    case SESSION_AVAILABLE:         //4
8238
                        $session['visibility'] = get_lang('Visible');
8239
                        break;
8240
                    case SESSION_INVISIBLE:         //3
8241
                        $session['visibility'] = api_ucfirst(get_lang('Invisible'));
8242
                        break;
8243
                }
8244
8245
                // Cleaning double selects
8246
                foreach ($session as $key => &$value) {
8247
                    if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
8248
                        $options = explode('::', $value);
8249
                    }
8250
                    $original_key = $key;
8251
8252
                    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...
8253
                    } else {
8254
                        $key = str_replace('_second', '', $key);
8255
                    }
8256
8257
                    if (isset($options_by_double[$key])) {
8258
                        if (isset($options[0])) {
8259
                            if (isset($options_by_double[$key][$options[0]])) {
8260
                                if (strpos($original_key, '_second') === false) {
8261
                                    $value = $options_by_double[$key][$options[0]]['option_display_text'];
8262
                                } else {
8263
                                    $value = $options_by_double[$key][$options[1]]['option_display_text'];
8264
                                }
8265
                            }
8266
                        }
8267
                    }
8268
                }
8269
8270
                // Magic filter
8271
                if (isset($formatted_sessions[$session_id])) {
8272
                    $formatted_sessions[$session_id] = self::compareArraysToMerge(
8273
                        $formatted_sessions[$session_id],
8274
                        $session
8275
                    );
8276
                } else {
8277
                    $formatted_sessions[$session_id] = $session;
8278
                }
8279
            }
8280
        }
8281
8282
        return $formatted_sessions;
8283
    }
8284
8285
    /**
8286
     * Compare two arrays
8287
     * @param array $array1
8288
     * @param array $array2
8289
     *
8290
     * @return array
8291
     */
8292
    public static function compareArraysToMerge($array1, $array2)
8293
    {
8294
        if (empty($array2)) {
8295
            return $array1;
8296
        }
8297
        foreach ($array1 as $key => $item) {
8298
            if (!isset($array1[$key])) {
8299
                //My string is empty try the other one
8300
                if (isset($array2[$key]) && !empty($array2[$key])) {
8301
                    $array1[$key] = $array2[$key];
8302
                }
8303
            }
8304
        }
8305
        return $array1;
8306
    }
8307
8308
    /**
8309
     * Get link to the admin page for this session
8310
     * @param   int $id Session ID
8311
     * @return mixed    URL to the admin page to manage the session, or false on error
8312
     */
8313
    public static function getAdminPath($id)
8314
    {
8315
        $id = intval($id);
8316
        $session = self::fetch($id);
8317
        if (empty($session)) {
8318
            return false;
8319
        }
8320
        return api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$id;
8321
    }
8322
8323
    /**
8324
     * Get link to the user page for this session.
8325
     * If a course is provided, build the link to the course
8326
     * @param   int $id Session ID
8327
     * @param   int $courseId Course ID (optional) in case the link has to send straight to the course
8328
     * @return mixed    URL to the page to use the session, or false on error
8329
     */
8330
    public static function getPath($id, $courseId = 0)
8331
    {
8332
        $id = intval($id);
8333
        $session = self::fetch($id);
8334
        if (empty($session)) {
8335
            return false;
8336
        }
8337
        if (empty($courseId)) {
8338
            return api_get_path(WEB_CODE_PATH).'session/index.php?session_id='.$id;
8339
        } else {
8340
            $courseInfo = api_get_course_info_by_id($courseId);
8341
            if ($courseInfo) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $courseInfo of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
8342
                return $courseInfo['course_public_url'].'?id_session='.$id;
8343
            }
8344
        }
8345
8346
        return false;
8347
    }
8348
8349
    /**
8350
     * Return an associative array 'id_course' => [id_session1, id_session2...]
8351
     * where course id_course is in sessions id_session1, id_session2
8352
     * for course where user is coach
8353
     * i.e. coach for the course or
8354
     * main coach for a session the course is in
8355
     * for a session category (or woth no session category if empty)
8356
     *
8357
     * @param int $userId
8358
     *
8359
     * @return array
8360
     */
8361
    public static function getSessionCourseForUser($userId)
8362
    {
8363
        // list of COURSES where user is COURSE session coach
8364
        $listCourseCourseCoachSession = self::getCoursesForCourseSessionCoach($userId);
8365
        // list of courses where user is MAIN session coach
8366
        $listCourseMainCoachSession = self::getCoursesForMainSessionCoach($userId);
8367
        // merge these 2 array
8368
        $listResCourseSession = $listCourseCourseCoachSession;
8369
        foreach ($listCourseMainCoachSession as $courseId2 => $listSessionId2) {
8370
            if (isset($listResCourseSession[$courseId2])) {
8371
                // if sessionId array exists for this course
8372
                // same courseId, merge the list of session
8373
                foreach ($listCourseMainCoachSession[$courseId2] as $i => $sessionId2) {
8374
                    if (!in_array($sessionId2, $listResCourseSession[$courseId2])) {
8375
                        $listResCourseSession[$courseId2][] = $sessionId2;
8376
                    }
8377
                }
8378
            } else {
8379
                $listResCourseSession[$courseId2] = $listSessionId2;
8380
            }
8381
        }
8382
8383
        return $listResCourseSession;
8384
    }
8385
8386
    /**
8387
     * Return an associative array 'id_course' => [id_session1, id_session2...]
8388
     * where course id_course is in sessions id_session1, id_session2
8389
     * @param $userId
8390
     *
8391
     * @return array
8392
     */
8393
    public static function getCoursesForCourseSessionCoach($userId)
8394
    {
8395
        $listResCourseSession = [];
8396
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
8397
        $tblSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
8398
8399
        $sql = "SELECT session_id, c_id, c.id
8400
                FROM $tblSessionRelCourseRelUser srcru
8401
                LEFT JOIN $tblCourse c
8402
                ON c.id = srcru.c_id
8403
                WHERE
8404
                    srcru.user_id =".intval($userId)." AND
8405
                    srcru.status = 2";
8406
8407
        $res = Database::query($sql);
8408
8409
        while ($data = Database::fetch_assoc($res)) {
8410
            if (api_get_session_visibility($data['session_id'])) {
8411
                if (!isset($listResCourseSession[$data['id']])) {
8412
                    $listResCourseSession[$data['id']] = [];
8413
                }
8414
                $listResCourseSession[$data['id']][] = $data['session_id'];
8415
            }
8416
        }
8417
8418
        return $listResCourseSession;
8419
    }
8420
8421
    /**
8422
     * Return an associative array 'id_course' => [id_session1, id_session2...]
8423
     * where course id_course is in sessions id_session1, id_session2
8424
     * @param $userId
8425
     *
8426
     * @return array
8427
     */
8428
    public static function getCoursesForMainSessionCoach($userId)
8429
    {
8430
        $listResCourseSession = [];
8431
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
8432
8433
        // list of SESSION where user is session coach
8434
        $sql = "SELECT id FROM $tblSession
8435
                WHERE id_coach = ".intval($userId);
8436
        $res = Database::query($sql);
8437
8438
        while ($data = Database::fetch_assoc($res)) {
8439
            $sessionId = $data['id'];
8440
            $listCoursesInSession = self::getCoursesInSession($sessionId);
8441
            foreach ($listCoursesInSession as $i => $courseId) {
8442
                if (api_get_session_visibility($sessionId)) {
8443
                    if (!isset($listResCourseSession[$courseId])) {
8444
                        $listResCourseSession[$courseId] = [];
8445
                    }
8446
                    $listResCourseSession[$courseId][] = $sessionId;
8447
                }
8448
            }
8449
        }
8450
8451
        return $listResCourseSession;
8452
    }
8453
8454
    /**
8455
     * Return an array of course_id used in session $sessionId
8456
     * @param $sessionId
8457
     *
8458
     * @return array
8459
     */
8460
    public static function getCoursesInSession($sessionId)
8461
    {
8462
        if (empty($sessionId)) {
8463
            return [];
8464
        }
8465
8466
        $tblSessionRelCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
8467
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
8468
8469
        // list of course in this session
8470
        $sql = "SELECT session_id, c.id
8471
                FROM $tblSessionRelCourse src
8472
                LEFT JOIN $tblCourse c
8473
                ON c.id = src.c_id
8474
                WHERE session_id = ".intval($sessionId);
8475
        $res = Database::query($sql);
8476
8477
        $listResultsCourseId = [];
8478
        while ($data = Database::fetch_assoc($res)) {
8479
            $listResultsCourseId[] = $data['id'];
8480
        }
8481
8482
        return $listResultsCourseId;
8483
    }
8484
8485
    /**
8486
     * Return an array of courses in session for user
8487
     * and for each courses the list of session that use this course for user
8488
     *
8489
     * [0] => array
8490
     *      userCatId
8491
     *      userCatTitle
8492
     *      courseInUserCatList
8493
     *          [0] => array
8494
     *              courseId
8495
     *              title
8496
     *              courseCode
8497
     *              sessionCatList
8498
     *                  [0] => array
8499
     *                      catSessionId
8500
     *                      catSessionName
8501
     *                      sessionList
8502
     *                          [0] => array
8503
     *                              sessionId
8504
     *                              sessionName
8505
     *
8506
     * @param int $userId
8507
     *
8508
     * @return array
8509
     *
8510
     */
8511
    public static function getNamedSessionCourseForCoach($userId)
8512
    {
8513
        $listResults = [];
8514
        $listCourseSession = self::getSessionCourseForUser($userId);
8515
        foreach ($listCourseSession as $courseId => $listSessionId) {
8516
            // Course info
8517
            $courseInfo = api_get_course_info_by_id($courseId);
8518
            $listOneCourse = [];
8519
            $listOneCourse['courseId'] = $courseId;
8520
            $listOneCourse['title'] = $courseInfo['title'];
8521
            //$listOneCourse['courseCode'] = $courseInfo['code'];
8522
            $listOneCourse['course'] = $courseInfo;
8523
            $listOneCourse['sessionCatList'] = [];
8524
            $listCat = [];
8525
            foreach ($listSessionId as $i => $sessionId) {
8526
                // here we got all session for this course
8527
                // lets check there session categories
8528
                $sessionInfo = self::fetch($sessionId);
8529
                $catId = $sessionInfo['session_category_id'];
8530
                if (!isset($listCat[$catId])) {
8531
                    $listCatInfo = self::get_session_category($catId);
8532
                    $listCat[$catId] = [];
8533
                    $listCat[$catId]['catSessionId'] = $catId;
8534
                    $listCat[$catId]['catSessionName'] = $listCatInfo['name'];
8535
                    $listCat[$catId]['sessionList'] = [];
8536
                }
8537
                $listSessionInfo = self::fetch($sessionId);
8538
                $listSessionIdName = [
8539
                    "sessionId" => $sessionId,
8540
                    "sessionName" => $listSessionInfo['name'],
8541
                ];
8542
                $listCat[$catId]['sessionList'][] = $listSessionIdName;
8543
            }
8544
            // sort $listCat by catSessionName
8545
            usort($listCat, 'self::compareBySessionName');
8546
            // in each catSession sort sessionList by sessionName
8547
            foreach ($listCat as $i => $listCatSessionInfo) {
8548
                $listSessionList = $listCatSessionInfo['sessionList'];
8549
                usort($listSessionList, 'self::compareCatSessionInfo');
8550
                $listCat[$i]['sessionList'] = $listSessionList;
8551
            }
8552
8553
            $listOneCourse['sessionCatList'] = $listCat;
8554
8555
            // user course category
8556
            $courseCategory = CourseManager::getUserCourseCategoryForCourse(
8557
                $userId,
8558
                $courseId
8559
            );
8560
8561
            $userCatTitle = '';
8562
            $userCatId = 0;
8563
            if ($courseCategory) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $courseCategory of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
8564
                $userCatId = $courseCategory['user_course_cat'];
8565
                $userCatTitle = $courseCategory['title'];
8566
            }
8567
8568
            $listResults[$userCatId]['courseInUserCategoryId'] = $userCatId;
8569
            $listResults[$userCatId]['courseInUserCategoryTitle'] = $userCatTitle;
8570
            $listResults[$userCatId]['courseInUserCatList'][] = $listOneCourse;
8571
        }
8572
8573
        // sort by user course cat
8574
        uasort($listResults, 'self::compareByUserCourseCat');
8575
8576
        // sort by course title
8577
        foreach ($listResults as $userCourseCatId => $tabCoursesInCat) {
8578
            $courseInUserCatList = $tabCoursesInCat['courseInUserCatList'];
8579
            uasort($courseInUserCatList, 'self::compareByCourse');
8580
            $listResults[$userCourseCatId]['courseInUserCatList'] = $courseInUserCatList;
8581
        }
8582
8583
        return $listResults;
8584
    }
8585
8586
    /**
8587
     * @param array $listA
8588
     * @param array $listB
8589
     * @return int
8590
     */
8591
    private static function compareCatSessionInfo($listA, $listB)
8592
    {
8593
        if ($listA['sessionName'] == $listB['sessionName']) {
8594
            return 0;
8595
        } elseif ($listA['sessionName'] > $listB['sessionName']) {
8596
            return 1;
8597
        } else {
8598
            return -1;
8599
        }
8600
    }
8601
8602
    /**
8603
     * @param array $listA
8604
     * @param array $listB
8605
     * @return int
8606
     */
8607
    private static function compareBySessionName($listA, $listB)
8608
    {
8609
        if ($listB['catSessionName'] == '') {
8610
            return -1;
8611
        } elseif ($listA['catSessionName'] == '') {
8612
            return 1;
8613
        } elseif ($listA['catSessionName'] == $listB['catSessionName']) {
8614
            return 0;
8615
        } elseif ($listA['catSessionName'] > $listB['catSessionName']) {
8616
            return 1;
8617
        } else {
8618
            return -1;
8619
        }
8620
    }
8621
8622
    /**
8623
     * @param array $listA
8624
     * @param array $listB
8625
     * @return int
8626
     */
8627
    private static function compareByUserCourseCat($listA, $listB)
8628
    {
8629
        if ($listA['courseInUserCategoryTitle'] == $listB['courseInUserCategoryTitle']) {
8630
            return 0;
8631
        } elseif ($listA['courseInUserCategoryTitle'] > $listB['courseInUserCategoryTitle']) {
8632
            return 1;
8633
        } else {
8634
            return -1;
8635
        }
8636
    }
8637
8638
    /**
8639
     * @param array $listA
8640
     * @param array $listB
8641
     * @return int
8642
     */
8643
    private static function compareByCourse($listA, $listB)
8644
    {
8645
        if ($listA['title'] == $listB['title']) {
8646
            return 0;
8647
        } elseif ($listA['title'] > $listB['title']) {
8648
            return 1;
8649
        } else {
8650
            return -1;
8651
        }
8652
    }
8653
8654
    /**
8655
     * Return HTML code for displaying session_course_for_coach
8656
     * @param $userId
8657
     * @return string
8658
     */
8659
    public static function getHtmlNamedSessionCourseForCoach($userId)
8660
    {
8661
        $htmlRes = '';
8662
        $listInfo = self::getNamedSessionCourseForCoach($userId);
8663
        foreach ($listInfo as $i => $listCoursesInfo) {
8664
            $courseInfo = $listCoursesInfo['course'];
8665
            $courseCode = $listCoursesInfo['course']['code'];
8666
8667
            $listParamsCourse = [];
8668
            $listParamsCourse['icon'] = '<div style="float:left">
8669
                <input style="border:none;" type="button" onclick="$(\'#course-'.$courseCode.'\').toggle(\'fast\')" value="+" /></div>'.
8670
                Display::return_icon('blackboard.png', $courseInfo['title'], [], ICON_SIZE_LARGE);
8671
            $listParamsCourse['link'] = '';
8672
            $listParamsCourse['title'] = Display::tag(
8673
                'a',
8674
                $courseInfo['title'],
8675
                ['href' => $listParamsCourse['link']]
8676
            );
8677
            $htmlCourse = '<div class="well" style="border-color:#27587D">'.
8678
                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()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

8678
                CourseManager::/** @scrutinizer ignore-call */ 
8679
                               course_item_html($listParamsCourse, true);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
8679
            // for each category of session
8680
            $htmlCatSessions = '';
8681
            foreach ($listCoursesInfo['sessionCatList'] as $j => $listCatSessionsInfo) {
8682
                // we got an array of session categories
8683
                $catSessionId = $listCoursesInfo['sessionCatList'][$j]['catSessionId'];
8684
                $catSessionName = $listCoursesInfo['sessionCatList'][$j]['catSessionName'];
8685
8686
                $listParamsCatSession['icon'] = Display::return_icon('folder_blue.png', $catSessionName, [], ICON_SIZE_LARGE);
8687
                $listParamsCatSession['link'] = '';
8688
                $listParamsCatSession['title'] = $catSessionName;
8689
8690
                $marginShift = 20;
8691
                if ($catSessionName != '') {
8692
                    $htmlCatSessions .= '<div style="margin-left:'.$marginShift.'px;">'.
8693
                        CourseManager::course_item_html($listParamsCatSession, true).'</div>';
8694
                    $marginShift = 40;
8695
                }
8696
8697
                // for each sessions
8698
                $listCatSessionSessionList = $listCoursesInfo['sessionCatList'][$j]['sessionList'];
8699
                $htmlSession = '';
8700
                foreach ($listCatSessionSessionList as $k => $listSessionInfo) {
8701
                    // we got an array of session info
8702
                    $sessionId = $listSessionInfo['sessionId'];
8703
                    $sessionName = $listSessionInfo['sessionName'];
8704
8705
                    $listParamsSession['icon'] = Display::return_icon('blackboard_blue.png', $sessionName, [], ICON_SIZE_LARGE);
8706
                    $listParamsSession['link'] = '';
8707
                    $linkToCourseSession = $courseInfo['course_public_url'].'?id_session='.$sessionId;
8708
                    $listParamsSession['title'] =
8709
                        $sessionName.'<div style="font-weight:normal; font-style:italic">
8710
                            <a href="'.$linkToCourseSession.'">'.get_lang('GoToCourseInsideSession').'</a>
8711
                            </div>';
8712
                    $htmlSession .= '<div style="margin-left:'.$marginShift.'px;">'.
8713
                        CourseManager::course_item_html($listParamsSession, true).'</div>';
8714
                }
8715
                $htmlCatSessions .= $htmlSession;
8716
            }
8717
            $htmlRes .= $htmlCourse.'<div style="display:none" id="course-'.$courseCode.'">'.$htmlCatSessions.'</div></div>';
8718
        }
8719
8720
        return $htmlRes;
8721
    }
8722
8723
    /**
8724
     * @param int $userId
8725
     * @param int $courseId
8726
     *
8727
     * @return array
8728
     */
8729
    public static function searchCourseInSessionsFromUser($userId, $courseId)
8730
    {
8731
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
8732
        $userId = (int) $userId;
8733
        $courseId = (int) $courseId;
8734
        if (empty($userId) || empty($courseId)) {
8735
            return [];
8736
        }
8737
8738
        $sql = "SELECT * FROM $table 
8739
                WHERE c_id = $courseId AND user_id = $userId";
8740
        $result = Database::query($sql);
8741
8742
        return Database::store_result($result, 'ASSOC');
8743
    }
8744
8745
    /**
8746
     * Subscribe and redirect to session after inscription
8747
     */
8748
    public static function redirectToSession()
8749
    {
8750
        $sessionId = ChamiloSession::read('session_redirect');
8751
        $onlyOneCourseSessionToRedirect = ChamiloSession::read('only_one_course_session_redirect');
8752
        if ($sessionId) {
8753
            $sessionInfo = api_get_session_info($sessionId);
8754
            if (!empty($sessionInfo)) {
8755
                $userId = api_get_user_id();
8756
                $response = self::isUserSubscribedAsStudent($sessionId, $userId);
8757
                if ($response) {
8758
                    $urlToRedirect = api_get_path(WEB_CODE_PATH).'session/index.php?session_id='.$sessionId;
8759
                    if (!empty($onlyOneCourseSessionToRedirect)) {
8760
                        $urlToRedirect = api_get_path(WEB_PATH).'courses/'.$onlyOneCourseSessionToRedirect.'/index.php?id_session='.$sessionId;
8761
                    }
8762
8763
                    header('Location: '.$urlToRedirect);
8764
                    exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
8765
                }
8766
            }
8767
        }
8768
    }
8769
8770
    /**
8771
     * @param Course $course
8772
     * @param Session $session
8773
     * @return int
8774
     */
8775
    public static function getCountUsersInCourseSession(
8776
        Course $course,
8777
        Session $session
8778
    ) {
8779
        return Database::getManager()
8780
            ->createQuery("
8781
                SELECT COUNT(scu)
8782
                FROM ChamiloCoreBundle:SessionRelCourseRelUser scu
8783
                INNER JOIN ChamiloCoreBundle:SessionRelUser su
8784
                    WITH scu.user = su.user
8785
                    AND scu.session = su.session
8786
                WHERE 
8787
                    scu.course = :course AND 
8788
                    su.relationType <> :relationType AND 
8789
                    scu.session = :session
8790
            ")
8791
            ->setParameters([
8792
                'course' => $course->getId(),
8793
                'relationType' => SESSION_RELATION_TYPE_RRHH,
8794
                'session' => $session->getId()
8795
            ])
8796
            ->getSingleScalarResult();
8797
    }
8798
8799
    /**
8800
     * Get course IDs where user in not subscribed in session
8801
     * @param User $user
8802
     * @param Session $session
8803
     * @return array
8804
     */
8805
    public static function getAvoidedCoursesInSession(User $user, Session $session)
8806
    {
8807
        $courseIds = [];
8808
8809
        /** @var SessionRelCourse $sessionCourse */
8810
        foreach ($session->getCourses() as $sessionCourse) {
8811
            /** @var Course $course */
8812
            $course = $sessionCourse->getCourse();
8813
8814
            if ($session->getUserInCourse($user, $course)->count()) {
0 ignored issues
show
Bug introduced by
The method count() does not exist on Chamilo\CoreBundle\Entity\Session. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

8814
            if ($session->getUserInCourse($user, $course)->/** @scrutinizer ignore-call */ count()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
8815
                continue;
8816
            }
8817
8818
            $courseIds[] = $course->getId();
8819
        }
8820
8821
        return $courseIds;
8822
    }
8823
}
8824