Passed
Push — 1.11.x ( 7d8933...df4111 )
by Julito
16:13
created

GroupManager::get_users()   B

Complexity

Conditions 11
Paths 96

Size

Total Lines 61
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 36
nc 96
nop 8
dl 0
loc 61
rs 7.3166
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\CourseBundle\Entity\CGroupRelUser;
5
6
/**
7
 * This library contains some functions for group-management.
8
 *
9
 * @author Bart Mollet
10
 *
11
 * @todo Add $course_code parameter to all functions. So this GroupManager can
12
 * be used outside a session.
13
 */
14
class GroupManager
15
{
16
    /* DEFAULT_GROUP_CATEGORY:
17
    When group categories aren't available (platform-setting),
18
    all groups are created in this 'dummy'-category*/
19
    const DEFAULT_GROUP_CATEGORY = 2;
20
21
    /**
22
     * infinite.
23
     */
24
    const INFINITE = 99999;
25
    /**
26
     * No limit on the number of users in a group.
27
     */
28
    const MEMBER_PER_GROUP_NO_LIMIT = 0;
29
    /**
30
     * No limit on the number of groups per user.
31
     */
32
    const GROUP_PER_MEMBER_NO_LIMIT = 0;
33
    /**
34
     * The tools of a group can have 3 states
35
     * - not available
36
     * - public
37
     * - private.
38
     */
39
    const TOOL_NOT_AVAILABLE = 0;
40
    const TOOL_PUBLIC = 1;
41
    const TOOL_PRIVATE = 2;
42
    const TOOL_PRIVATE_BETWEEN_USERS = 3;
43
44
    /**
45
     * Constants for the available group tools.
46
     */
47
    const GROUP_TOOL_FORUM = 0;
48
    const GROUP_TOOL_DOCUMENTS = 1;
49
    const GROUP_TOOL_CALENDAR = 2;
50
    const GROUP_TOOL_ANNOUNCEMENT = 3;
51
    const GROUP_TOOL_WORK = 4;
52
    const GROUP_TOOL_WIKI = 5;
53
    const GROUP_TOOL_CHAT = 6;
54
55
    const DOCUMENT_MODE_SHARE = 0; // By default
56
    const DOCUMENT_MODE_READ_ONLY = 1;
57
    const DOCUMENT_MODE_COLLABORATION = 2;
58
59
    /**
60
     * GroupManager constructor.
61
     */
62
    public function __construct()
63
    {
64
    }
65
66
    /**
67
     * @param int $courseId
68
     *
69
     * @return array
70
     */
71
    public static function get_groups($courseId = 0)
72
    {
73
        $table_group = Database::get_course_table(TABLE_GROUP);
74
        $courseId = !empty($courseId) ? (int) $courseId : api_get_course_int_id();
75
76
        $sql = "SELECT * FROM $table_group WHERE c_id = $courseId  ";
77
        $result = Database::query($sql);
78
79
        return Database::store_result($result, 'ASSOC');
80
    }
81
82
    /**
83
     * Get list of groups for current course.
84
     *
85
     * @param int   $categoryId  The id of the category from which the groups are
86
     *                           requested
87
     * @param array $course_info Default is current course
88
     * @param int   $status      group status
89
     * @param int   $sessionId
90
     * @param bool  $getCount
91
     *
92
     * @return array an array with all information about the groups
93
     */
94
    public static function get_group_list(
95
        $categoryId = null,
96
        $course_info = [],
97
        $status = null,
98
        $sessionId = 0,
99
        $getCount = false
100
    ) {
101
        $course_info = empty($course_info) ? api_get_course_info() : $course_info;
102
        if (empty($course_info)) {
103
            return [];
104
        }
105
        $sessionId = empty($sessionId) ? api_get_session_id() : (int) $sessionId;
106
        $course_id = $course_info['real_id'];
107
        $table_group = Database::get_course_table(TABLE_GROUP);
108
109
        $select = ' g.id,
110
                    g.iid,
111
                    g.name,
112
                    g.description,
113
                    g.category_id,
114
                    g.max_student maximum_number_of_members,
115
                    g.secret_directory,
116
                    g.self_registration_allowed,
117
                    g.self_unregistration_allowed,
118
                    g.session_id,
119
                    g.status';
120
        if ($getCount) {
121
            $select = ' DISTINCT count(g.iid) as count ';
122
        }
123
124
        $sql = "SELECT
125
                $select
126
                FROM $table_group g
127
                WHERE 1 = 1 ";
128
129
        if (!is_null($categoryId)) {
130
            $sql .= " AND g.category_id = '".intval($categoryId)."' ";
131
            $session_condition = api_get_session_condition($sessionId);
132
            if (!empty($session_condition)) {
133
                $sql .= $session_condition;
134
            }
135
        } else {
136
            $session_condition = api_get_session_condition($sessionId, true);
137
        }
138
139
        if (!is_null($status)) {
140
            $sql .= " AND g.status = '".intval($status)."' ";
141
        }
142
143
        $sql .= " AND g.c_id = $course_id ";
144
145
        if (!empty($session_condition)) {
146
            $sql .= $session_condition;
147
        }
148
        $sql .= ' ORDER BY UPPER(g.name)';
149
150
        $result = Database::query($sql);
151
152
        if ($getCount) {
153
            $row = Database::fetch_array($result);
154
155
            return $row['count'];
156
        }
157
158
        $groups = [];
159
        while ($thisGroup = Database::fetch_array($result)) {
160
            $thisGroup['number_of_members'] = count(self::get_subscribed_users($thisGroup));
161
            if ($thisGroup['session_id'] != 0) {
162
                $sql = 'SELECT name FROM '.Database::get_main_table(TABLE_MAIN_SESSION).'
163
                        WHERE id='.$thisGroup['session_id'];
164
                $rs_session = Database::query($sql);
165
                if (Database::num_rows($rs_session) > 0) {
166
                    $thisGroup['session_name'] = Database::result($rs_session, 0, 0);
167
                }
168
            }
169
            $groups[] = $thisGroup;
170
        }
171
172
        return $groups;
173
    }
174
175
    /**
176
     * Create a group.
177
     *
178
     * @param string $name        The name for this group
179
     * @param int    $category_id
180
     * @param int    $tutor       The user-id of the group's tutor
181
     * @param int    $places      How many people can subscribe to the new group
182
     *
183
     * @return int
184
     */
185
    public static function create_group($name, $category_id, $tutor, $places)
186
    {
187
        $_course = api_get_course_info();
188
        $session_id = api_get_session_id();
189
        $course_id = $_course['real_id'];
190
        $currentCourseRepository = $_course['path'];
191
        $category = self::get_category($category_id);
192
        $places = (int) $places;
193
194
        // Default values
195
        $docState = self::TOOL_PRIVATE;
196
        $calendarState = self::TOOL_PRIVATE;
197
        $workState = self::TOOL_PRIVATE;
198
        $anonuncementState = self::TOOL_PRIVATE;
199
        $forumState = self::TOOL_PRIVATE;
200
        $wikiState = self::TOOL_PRIVATE;
201
        $chatState = self::TOOL_PRIVATE;
202
        $selfRegAllowed = 0;
203
        $selfUnregAllwoed = 0;
204
        $documentAccess = 0;
205
206
        if ($category) {
207
            if ($places == 0) {
208
                //if the amount of users per group is not filled in, use the setting from the category
209
                $places = $category['max_student'];
210
            } else {
211
                if ($places > $category['max_student'] && $category['max_student'] != 0) {
212
                    $places = $category['max_student'];
213
                }
214
            }
215
            $docState = $category['doc_state'];
216
            $calendarState = $category['calendar_state'];
217
            $workState = $category['work_state'];
218
            $anonuncementState = $category['announcements_state'];
219
            $forumState = $category['forum_state'];
220
            $wikiState = $category['wiki_state'];
221
            $chatState = $category['chat_state'];
222
            $selfRegAllowed = $category['self_reg_allowed'];
223
            $selfUnregAllwoed = $category['self_unreg_allowed'];
224
            $documentAccess = isset($category['document_access']) ? $category['document_access'] : 0;
225
        }
226
227
        $allowDocumentAccess = api_get_configuration_value('group_document_access');
228
        $documentCondition = '';
229
        if ($allowDocumentAccess) {
230
            $documentAccess = (int) $documentAccess;
231
            $documentCondition = " document_access = $documentAccess, ";
232
        }
233
234
        $table_group = Database::get_course_table(TABLE_GROUP);
235
        $sql = "INSERT INTO $table_group SET
236
                c_id = $course_id,
237
                status = 1,
238
                category_id='".Database::escape_string($category_id)."',
239
                max_student = '".$places."',
240
                doc_state = '".$docState."',
241
                calendar_state = '".$calendarState."',
242
                work_state = '".$workState."',
243
                announcements_state = '".$anonuncementState."',
244
                forum_state = '".$forumState."',
245
                wiki_state = '".$wikiState."',
246
                chat_state = '".$chatState."',
247
                self_registration_allowed = '".$selfRegAllowed."',
248
                self_unregistration_allowed = '".$selfUnregAllwoed."',
249
                $documentCondition
250
                session_id='".$session_id."'";
251
252
        Database::query($sql);
253
        $lastId = Database::insert_id();
254
255
        if ($lastId) {
256
            $sql = "UPDATE $table_group SET id = iid WHERE iid = $lastId";
257
            Database::query($sql);
258
259
            $desired_dir_name = '/'.api_replace_dangerous_char($name).'_groupdocs';
260
            $my_path = api_get_path(SYS_COURSE_PATH).$currentCourseRepository.'/document';
261
262
            $newFolderData = create_unexisting_directory(
263
                $_course,
264
                api_get_user_id(),
265
                $session_id,
266
                $lastId,
267
                null,
268
                $my_path,
269
                $desired_dir_name,
270
                null,
271
                1
272
            );
273
274
            $unique_name = $newFolderData['path'];
275
276
            /* Stores the directory path into the group table */
277
            $sql = "UPDATE $table_group SET
278
                        name = '".Database::escape_string($name)."',
279
                        secret_directory = '".$unique_name."'
280
                    WHERE c_id = $course_id AND id ='".$lastId."'";
281
282
            Database::query($sql);
283
284
            // create a forum if needed
285
            if ($forumState >= 0) {
286
                require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
287
288
                $forum_categories = get_forum_categories();
289
                if (empty($forum_categories)) {
290
                    $categoryParam = [
291
                        'forum_category_title' => get_lang('GroupForums'),
292
                    ];
293
                    store_forumcategory($categoryParam);
294
                    $forum_categories = get_forum_categories();
295
                }
296
297
                $counter = 0;
298
                foreach ($forum_categories as $key => $value) {
299
                    if ($counter == 0) {
300
                        $forum_category_id = $key;
301
                    }
302
                    $counter++;
303
                }
304
                // A sanity check.
305
                if (empty($forum_category_id)) {
306
                    $forum_category_id = 0;
307
                }
308
309
                $values = [];
310
                $values['forum_title'] = $name;
311
                $values['group_id'] = $lastId;
312
                $values['forum_category'] = $forum_category_id;
313
                $values['allow_anonymous_group']['allow_anonymous'] = 0;
314
                $values['students_can_edit_group']['students_can_edit'] = 0;
315
                $values['approval_direct_group']['approval_direct'] = 0;
316
                $values['allow_attachments_group']['allow_attachments'] = 1;
317
                $values['allow_new_threads_group']['allow_new_threads'] = 1;
318
                $values['default_view_type_group']['default_view_type'] = api_get_setting('default_forum_view');
319
                $values['group_forum'] = $lastId;
320
                if ($forumState == '1') {
321
                    $values['public_private_group_forum_group']['public_private_group_forum'] = 'public';
322
                } elseif ($forumState == '2') {
323
                    $values['public_private_group_forum_group']['public_private_group_forum'] = 'private';
324
                } elseif ($forumState == '0') {
325
                    $values['public_private_group_forum_group']['public_private_group_forum'] = 'unavailable';
326
                }
327
                store_forum($values);
328
            }
329
        }
330
331
        return $lastId;
332
    }
333
334
    /**
335
     * Create subgroups.
336
     * This function creates new groups based on an existing group. It will
337
     * create the specified number of groups and fill those groups with users
338
     * from the base group.
339
     *
340
     * @param int $group_id         the group from which subgroups have to be created
341
     * @param int $number_of_groups The number of groups that have to be created
342
     */
343
    public static function create_subgroups($group_id, $number_of_groups)
344
    {
345
        $courseId = api_get_course_int_id();
346
        $table_group = Database::get_course_table(TABLE_GROUP);
347
        $category_id = self::create_category(
348
            get_lang('Subgroups'),
349
            '',
350
            self::TOOL_PRIVATE,
351
            self::TOOL_PRIVATE,
352
            0,
353
            0,
354
            1,
355
            1
356
        );
357
        $users = self::get_users($group_id);
358
        $group_ids = [];
359
360
        for ($group_nr = 1; $group_nr <= $number_of_groups; $group_nr++) {
361
            $group_ids[] = self::create_group(
362
                get_lang('Subgroup').' '.$group_nr,
363
                $category_id,
364
                0,
365
                0
366
            );
367
        }
368
369
        $members = [];
370
        foreach ($users as $index => $user_id) {
371
            $groupId = $group_ids[$index % $number_of_groups];
372
            $groupInfo = self::get_group_properties($groupId);
373
            self::subscribe_users(
374
                $user_id,
375
                $groupInfo
376
            );
377
            $members[$group_ids[$groupId]]++;
378
        }
379
380
        foreach ($members as $group_id => $places) {
381
            $sql = "UPDATE $table_group SET max_student = $places
382
                    WHERE c_id = $courseId  AND id = $group_id";
383
            Database::query($sql);
384
        }
385
    }
386
387
    /**
388
     * Create a group for every class subscribed to the current course.
389
     *
390
     * @param int $categoryId The category in which the groups should be created
391
     *
392
     * @return array
393
     */
394
    public static function create_class_groups($categoryId)
395
    {
396
        $options['where'] = [' usergroup.course_id = ? ' => api_get_course_int_id()];
397
        $obj = new UserGroup();
398
        $classes = $obj->getUserGroupInCourse($options);
399
        $group_ids = [];
400
401
        foreach ($classes as $class) {
402
            $userList = $obj->get_users_by_usergroup($class['id']);
403
            $groupId = self::create_group(
404
                $class['name'],
405
                $categoryId,
406
                0,
407
                null
408
            );
409
410
            if ($groupId) {
411
                $groupInfo = self::get_group_properties($groupId);
412
                self::subscribe_users($userList, $groupInfo);
413
                $group_ids[] = $groupId;
414
            }
415
        }
416
417
        return $group_ids;
418
    }
419
420
    /**
421
     * Deletes groups and their data.
422
     *
423
     * @author Christophe Gesche <[email protected]>
424
     * @author Hugues Peeters <[email protected]>
425
     * @author Bart Mollet
426
     *
427
     * @param array  $groupInfo   iid
428
     * @param string $course_code Default is current course
429
     *
430
     * @return int - number of groups deleted
431
     */
432
    public static function deleteGroup($groupInfo, $course_code = null)
433
    {
434
        if (empty($groupInfo['iid'])) {
435
            return false;
436
        }
437
        $course_info = api_get_course_info($course_code);
438
        if (empty($course_info)) {
439
            return false;
440
        }
441
442
        $course_id = $course_info['real_id'];
443
444
        // Database table definitions
445
        $group_table = Database::get_course_table(TABLE_GROUP);
446
        $forum_table = Database::get_course_table(TABLE_FORUM);
447
        $groupInfo = self::get_group_properties($groupInfo['iid'], true);
448
        if ($groupInfo) {
449
            $groupIid = $groupInfo['iid'];
450
            $groupId = $groupInfo['id'];
451
            // Unsubscribe all users
452
            self::unsubscribe_all_users($groupInfo);
453
            self::unsubscribe_all_tutors($groupInfo);
454
455
            if (!empty($groupInfo['secret_directory'])) {
456
                $directory = $groupInfo['secret_directory'];
457
                // move group-documents to garbage
458
                $source_directory = api_get_path(SYS_COURSE_PATH).$course_info['path']."/document".$directory;
459
                // File to renamed
460
                $destination_dir = api_get_path(SYS_COURSE_PATH).$course_info['path']."/document".$directory.'_DELETED_'.$groupInfo['id'];
461
                //Deleting from document tool
462
                DocumentManager::delete_document(
463
                    $course_info,
464
                    $directory,
465
                    $source_directory
466
                );
467
468
                if (file_exists($source_directory)) {
469
                    if (api_get_setting('permanently_remove_deleted_files') === 'true') {
470
                        // Delete
471
                        my_delete($source_directory);
472
                    } else {
473
                        // Rename
474
                        rename($source_directory, $destination_dir);
475
                    }
476
                }
477
            }
478
479
            $sql = "DELETE FROM $forum_table
480
                    WHERE c_id = $course_id AND forum_of_group = $groupId ";
481
            Database::query($sql);
482
483
            // Delete item properties of this group.
484
            // to_group_id is related to c_group_info.iid
485
            $itemPropertyTable = Database::get_course_table(TABLE_ITEM_PROPERTY);
486
            $sql = "DELETE FROM $itemPropertyTable
487
                    WHERE c_id = $course_id AND to_group_id = $groupIid ";
488
            Database::query($sql);
489
490
            // delete the groups
491
            $sql = "DELETE FROM $group_table
492
                    WHERE c_id = $course_id AND iid = $groupIid ";
493
            Database::query($sql);
494
        }
495
496
        return true;
497
    }
498
499
    /**
500
     * Function needed only when deleting a course, in order to be sure that all group ids are deleted.
501
     *
502
     * @param int $courseId
503
     *
504
     * @return bool
505
     */
506
    public static function deleteAllGroupsFromCourse($courseId)
507
    {
508
        $courseId = (int) $courseId;
509
510
        if (empty($courseId)) {
511
            return false;
512
        }
513
514
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
515
        $sql = "SELECT iid FROM $table
516
                WHERE c_id = $courseId ";
517
        Database::query($sql);
518
519
        // Database table definitions
520
        $table = Database::get_course_table(TABLE_GROUP_USER);
521
        $sql = "DELETE FROM $table
522
                WHERE c_id = $courseId";
523
        Database::query($sql);
524
525
        $table = Database::get_course_table(TABLE_GROUP_TUTOR);
526
        $sql = "DELETE FROM $table
527
                WHERE c_id = $courseId";
528
        Database::query($sql);
529
530
        $groupTable = Database::get_course_table(TABLE_GROUP);
531
        $sql = "DELETE FROM $groupTable
532
                WHERE c_id = $courseId";
533
        Database::query($sql);
534
535
        return true;
536
    }
537
538
    /**
539
     * Get group properties.
540
     *
541
     * @param int  $group_id the group from which properties are requested
542
     * @param bool $useIid
543
     *
544
     * @return array All properties. Array-keys are:
545
     *               name, tutor_id, description, maximum_number_of_students,
546
     *               directory and visibility of tools
547
     */
548
    public static function get_group_properties($group_id, $useIid = false)
549
    {
550
        $course_id = api_get_course_int_id();
551
        $group_id = (int) $group_id;
552
553
        if (empty($group_id)) {
554
            return null;
555
        }
556
557
        $table_group = Database::get_course_table(TABLE_GROUP);
558
        $sql = "SELECT * FROM $table_group
559
                WHERE c_id = $course_id AND id = ".$group_id;
560
561
        if ($useIid) {
562
            $sql = "SELECT * FROM $table_group
563
                    WHERE c_id = $course_id AND iid = ".$group_id;
564
        }
565
        $db_result = Database::query($sql);
566
        $db_object = Database::fetch_object($db_result);
567
568
        $result = [];
569
        if ($db_object) {
570
            $result['id'] = $db_object->id;
571
            $result['iid'] = $db_object->iid;
572
            $result['name'] = $db_object->name;
573
            $result['status'] = $db_object->status;
574
            $result['description'] = $db_object->description;
575
            $result['maximum_number_of_students'] = $db_object->max_student;
576
            $result['max_student'] = $db_object->max_student;
577
            $result['doc_state'] = $db_object->doc_state;
578
            $result['work_state'] = $db_object->work_state;
579
            $result['calendar_state'] = $db_object->calendar_state;
580
            $result['announcements_state'] = $db_object->announcements_state;
581
            $result['forum_state'] = $db_object->forum_state;
582
            $result['wiki_state'] = $db_object->wiki_state;
583
            $result['chat_state'] = $db_object->chat_state;
584
            $result['directory'] = $db_object->secret_directory;
585
            $result['self_registration_allowed'] = $db_object->self_registration_allowed;
586
            $result['self_unregistration_allowed'] = $db_object->self_unregistration_allowed;
587
            $result['count_users'] = count(
588
                self::get_subscribed_users($result)
589
            );
590
            $result['count_tutor'] = count(
591
                self::get_subscribed_tutors($result)
592
            );
593
            $result['count_all'] = $result['count_users'] + $result['count_tutor'];
594
            $result['document_access'] = isset($db_object->document_access) ? $db_object->document_access : self::DOCUMENT_MODE_SHARE;
595
        }
596
597
        return $result;
598
    }
599
600
    /**
601
     * @param string $name
602
     * @param string $courseCode
603
     * @param int    $sessionId
604
     *
605
     * @return array
606
     */
607
    public static function getGroupByName($name, $courseCode = null, $sessionId = 0)
608
    {
609
        $name = trim($name);
610
611
        if (empty($name)) {
612
            return [];
613
        }
614
615
        $course_info = api_get_course_info($courseCode);
616
        $course_id = $course_info['real_id'];
617
        $name = Database::escape_string($name);
618
        $sessionId = empty($sessionId) ? api_get_session_id() : (int) $sessionId;
619
        $sessionCondition = api_get_session_condition($sessionId);
620
621
        $table = Database::get_course_table(TABLE_GROUP);
622
        $sql = "SELECT * FROM $table
623
                WHERE
624
                  c_id = $course_id AND
625
                  name = '$name'
626
                  $sessionCondition
627
                LIMIT 1";
628
        $res = Database::query($sql);
629
        $group = [];
630
        if (Database::num_rows($res)) {
631
            $group = Database::fetch_array($res, 'ASSOC');
632
        }
633
634
        return $group;
635
    }
636
637
    /**
638
     * @param int    $courseId
639
     * @param int    $categoryId
640
     * @param string $name
641
     *
642
     * @return array
643
     */
644
    public static function getGroupListFilterByName($name, $categoryId, $courseId)
645
    {
646
        $name = Database::escape_string(trim($name));
647
        $categoryId = (int) $categoryId;
648
        $courseId = (int) $courseId;
649
650
        if (empty($name)) {
651
            return [];
652
        }
653
        $table = Database::get_course_table(TABLE_GROUP);
654
        $sql = "SELECT * FROM $table
655
                WHERE c_id = $courseId AND name LIKE '%$name%'";
656
657
        if (!empty($categoryId)) {
658
            $sql .= " AND category_id = $categoryId";
659
        }
660
        $sql .= " ORDER BY name";
661
        $result = Database::query($sql);
662
663
        return Database::store_result($result, 'ASSOC');
664
    }
665
666
    /**
667
     * Set group properties
668
     * Changes the group's properties.
669
     *
670
     * @param int       Group Id
671
     * @param string    Group name
672
     * @param string    Group description
673
     * @param int       Max number of students in group
674
     * @param int       Document tool's visibility (0=none,1=private,2=public)
675
     * @param int       Work tool's visibility (0=none,1=private,2=public)
676
     * @param int       Calendar tool's visibility (0=none,1=private,2=public)
677
     * @param int       Announcement tool's visibility (0=none,1=private,2=public)
678
     * @param int       Forum tool's visibility (0=none,1=private,2=public)
679
     * @param int       Wiki tool's visibility (0=none,1=private,2=public)
680
     * @param int       Chat tool's visibility (0=none,1=private,2=public)
681
     * @param bool Whether self registration is allowed or not
682
     * @param bool Whether self unregistration is allowed or not
683
     * @param int $categoryId
684
     * @param int $documentAccess
685
     *
686
     * @return bool TRUE if properties are successfully changed, false otherwise
687
     */
688
    public static function set_group_properties(
689
        $group_id,
690
        $name,
691
        $description,
692
        $maximum_number_of_students,
693
        $doc_state,
694
        $work_state,
695
        $calendar_state,
696
        $announcements_state,
697
        $forum_state,
698
        $wiki_state,
699
        $chat_state,
700
        $selfRegistrationAllowed,
701
        $selfUnRegistrationAllowed,
702
        $categoryId = null,
703
        $documentAccess = 0
704
    ) {
705
        $table_group = Database::get_course_table(TABLE_GROUP);
706
        $table_forum = Database::get_course_table(TABLE_FORUM);
707
        $categoryId = (int) $categoryId;
708
        $group_id = (int) $group_id;
709
        $courseId = api_get_course_int_id();
710
711
        $allowDocumentAccess = api_get_configuration_value('group_document_access');
712
        $documentCondition = '';
713
        if ($allowDocumentAccess) {
714
            $documentAccess = (int) $documentAccess;
715
            $documentCondition = " document_access = $documentAccess, ";
716
        }
717
718
        $sql = "UPDATE ".$table_group." SET
719
                    name='".Database::escape_string(trim($name))."',
720
                    doc_state = '".Database::escape_string($doc_state)."',
721
                    work_state = '".Database::escape_string($work_state)."',
722
                    calendar_state = '".Database::escape_string($calendar_state)."',
723
                    announcements_state = '".Database::escape_string($announcements_state)."',
724
                    forum_state = '".Database::escape_string($forum_state)."',
725
                    wiki_state = '".Database::escape_string($wiki_state)."',
726
                    chat_state = '".Database::escape_string($chat_state)."',
727
                    description ='".Database::escape_string(trim($description))."',
728
                    max_student = '".Database::escape_string($maximum_number_of_students)."',
729
                    self_registration_allowed = '".Database::escape_string($selfRegistrationAllowed)."',
730
                    self_unregistration_allowed = '".Database::escape_string($selfUnRegistrationAllowed)."',
731
                    $documentCondition
732
                    category_id = ".$categoryId."
733
                WHERE c_id = $courseId AND id=".$group_id;
734
        $result = Database::query($sql);
735
736
        /* Here we are updating a field in the table forum_forum that perhaps
737
        duplicates the table group_info.forum_state cvargas*/
738
        $forum_state = (int) $forum_state;
739
        $sql2 = "UPDATE ".$table_forum." SET ";
740
        if (1 === $forum_state) {
741
            $sql2 .= " forum_group_public_private='public' ";
742
        } elseif (2 === $forum_state) {
743
            $sql2 .= " forum_group_public_private='private' ";
744
        } elseif (0 === $forum_state) {
745
            $sql2 .= " forum_group_public_private='unavailable' ";
746
        }
747
        $sql2 .= " WHERE c_id = $courseId AND forum_of_group=".$group_id;
748
        Database::query($sql2);
749
750
        return $result;
751
    }
752
753
    /**
754
     * Get the total number of groups for the current course.
755
     *
756
     * @return int the number of groups for the current course
757
     */
758
    public static function get_number_of_groups()
759
    {
760
        $courseId = api_get_course_int_id();
761
        $table = Database::get_course_table(TABLE_GROUP);
762
        $sql = "SELECT COUNT(id) AS number_of_groups
763
                FROM $table
764
                WHERE c_id = $courseId ";
765
        $res = Database::query($sql);
766
        $obj = Database::fetch_object($res);
767
768
        return $obj->number_of_groups;
769
    }
770
771
    /**
772
     * Get all categories.
773
     *
774
     * @param string $course_code The course (default = current course)
775
     *
776
     * @return array
777
     */
778
    public static function get_categories($course_code = null)
779
    {
780
        $course_info = api_get_course_info($course_code);
781
        $courseId = $course_info['real_id'];
782
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
783
        $sql = "SELECT * FROM $table
784
                WHERE c_id = $courseId
785
                ORDER BY display_order";
786
        $res = Database::query($sql);
787
        $cats = [];
788
        while ($cat = Database::fetch_array($res)) {
789
            $cats[] = $cat;
790
        }
791
792
        return $cats;
793
    }
794
795
    /**
796
     * Get a group category.
797
     *
798
     * @param int    $id          The category id
799
     * @param string $course_code The course (default = current course)
800
     *
801
     * @return array
802
     */
803
    public static function get_category($id, $course_code = null)
804
    {
805
        if (empty($id)) {
806
            return [];
807
        }
808
809
        $courseInfo = api_get_course_info($course_code);
810
        $courseId = $courseInfo['real_id'];
811
        $id = intval($id);
812
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
813
        $sql = "SELECT * FROM $table
814
                WHERE c_id = $courseId AND id = $id
815
                LIMIT 1";
816
        $res = Database::query($sql);
817
818
        return Database::fetch_array($res);
819
    }
820
821
    /**
822
     * Get a group category.
823
     *
824
     * @param string $title
825
     * @param string $course_code The course (default = current course)
826
     *
827
     * @return array
828
     */
829
    public static function getCategoryByTitle($title, $course_code = null)
830
    {
831
        $title = trim($title);
832
833
        if (empty($title)) {
834
            return [];
835
        }
836
837
        $course_info = api_get_course_info($course_code);
838
        $courseId = $course_info['real_id'];
839
        $title = Database::escape_string($title);
840
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
841
        $sql = "SELECT * FROM $table
842
                WHERE c_id = $courseId AND title = '$title'
843
                LIMIT 1";
844
        $res = Database::query($sql);
845
        $category = [];
846
        if (Database::num_rows($res)) {
847
            $category = Database::fetch_array($res, 'ASSOC');
848
        }
849
850
        return $category;
851
    }
852
853
    /**
854
     * Get the unique category of a given group.
855
     *
856
     * @param int    $group_id    The iid of the group
857
     * @param string $course_code The course in which the group is (default =
858
     *                            current course)
859
     *
860
     * @return array The category
861
     */
862
    public static function get_category_from_group($group_id, $course_code = '')
863
    {
864
        $table_group = Database::get_course_table(TABLE_GROUP);
865
        $table_group_cat = Database::get_course_table(TABLE_GROUP_CATEGORY);
866
867
        $group_id = (int) $group_id;
868
869
        if (empty($group_id)) {
870
            return [];
871
        }
872
873
        $course_info = api_get_course_info($course_code);
874
875
        if (empty($course_info)) {
876
            return false;
877
        }
878
879
        $courseId = $course_info['real_id'];
880
        $sql = "SELECT gc.* FROM $table_group_cat gc, $table_group g
881
                WHERE
882
                    gc.c_id = $courseId AND
883
                    g.c_id = $courseId AND
884
                    gc.id = g.category_id AND
885
                    g.iid = $group_id
886
                LIMIT 1";
887
        $res = Database::query($sql);
888
        $cat = [];
889
        if (Database::num_rows($res)) {
890
            $cat = Database::fetch_array($res);
891
        }
892
893
        return $cat;
894
    }
895
896
    /**
897
     * Delete a group category.
898
     *
899
     * @param int    $cat_id      The id of the category to delete
900
     * @param string $course_code The code in which the category should be
901
     *                            deleted (default = current course)
902
     *
903
     * @return bool
904
     */
905
    public static function delete_category($cat_id, $course_code = '')
906
    {
907
        $course_info = api_get_course_info($course_code);
908
        if (empty($course_info)) {
909
            return false;
910
        }
911
        $course_id = $course_info['real_id'];
912
913
        $table_group = Database::get_course_table(TABLE_GROUP);
914
        $table_group_cat = Database::get_course_table(TABLE_GROUP_CATEGORY);
915
        $cat_id = intval($cat_id);
916
        $sql = "SELECT iid FROM $table_group
917
                WHERE c_id = $course_id AND category_id='".$cat_id."'";
918
        $res = Database::query($sql);
919
        if (Database::num_rows($res) > 0) {
920
            while ($group = Database::fetch_object($res)) {
921
                // Delete all groups in category
922
                /*$groupInfo = self::get_group_properties($group->iid, true);
923
                self::deleteGroup($groupInfo, $course_code);
924
                */
925
                // Set the category to NULL to avoid losing groups in sessions.
926
                $sql = "UPDATE $table_group SET category_id = NULL WHERE iid = ".$group->iid;
927
                Database::query($sql);
928
            }
929
        }
930
        $sql = "DELETE FROM $table_group_cat
931
                WHERE c_id = $course_id  AND id='".$cat_id."'";
932
        Database::query($sql);
933
934
        return true;
935
    }
936
937
    /**
938
     * Create group category.
939
     *
940
     * @param string $title                      The title of the new category
941
     * @param string $description                The description of the new category
942
     * @param int    $doc_state
943
     * @param int    $work_state
944
     * @param int    $calendar_state
945
     * @param int    $announcements_state
946
     * @param int    $forum_state
947
     * @param int    $wiki_state
948
     * @param int    $chat_state
949
     * @param int    $selfRegistrationAllowed    allow users to self register
950
     * @param int    $selfUnRegistrationAllowed  allow user to self unregister
951
     * @param int    $maximum_number_of_students
952
     * @param int    $groups_per_user
953
     * @param int    $documentAccess             document access
954
     *
955
     * @return mixed
956
     */
957
    public static function create_category(
958
        $title,
959
        $description,
960
        $doc_state,
961
        $work_state,
962
        $calendar_state,
963
        $announcements_state,
964
        $forum_state,
965
        $wiki_state,
966
        $chat_state = 1,
967
        $selfRegistrationAllowed = 0,
968
        $selfUnRegistrationAllowed = 0,
969
        $maximum_number_of_students = 8,
970
        $groups_per_user = 0,
971
        $documentAccess = 0
972
    ) {
973
        if (empty($title)) {
974
            return false;
975
        }
976
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
977
        $course_id = api_get_course_int_id();
978
979
        $sql = "SELECT MAX(display_order)+1 as new_order
980
                FROM $table
981
                WHERE c_id = $course_id ";
982
        $res = Database::query($sql);
983
        $obj = Database::fetch_object($res);
984
        if (!isset($obj->new_order)) {
985
            $obj->new_order = 1;
986
        }
987
988
        $params = [
989
            'c_id' => $course_id,
990
            'title' => $title,
991
            'display_order' => $obj->new_order,
992
            'description' => $description,
993
            'doc_state' => $doc_state,
994
            'work_state' => $work_state,
995
            'calendar_state' => $calendar_state,
996
            'announcements_state' => $announcements_state,
997
            'forum_state' => $forum_state,
998
            'wiki_state' => $wiki_state,
999
            'chat_state' => $chat_state,
1000
            'groups_per_user' => $groups_per_user,
1001
            'self_reg_allowed' => $selfRegistrationAllowed,
1002
            'self_unreg_allowed' => $selfUnRegistrationAllowed,
1003
            'max_student' => $maximum_number_of_students,
1004
        ];
1005
1006
        $allowDocumentAccess = api_get_configuration_value('group_category_document_access');
1007
        if ($allowDocumentAccess) {
1008
            $params['document_access'] = $documentAccess;
1009
        }
1010
1011
        $categoryId = Database::insert($table, $params);
1012
        if ($categoryId) {
1013
            $sql = "UPDATE $table SET id = iid
1014
                    WHERE iid = $categoryId";
1015
            Database::query($sql);
1016
1017
            return $categoryId;
1018
        }
1019
1020
        return false;
1021
    }
1022
1023
    /**
1024
     * Update group category.
1025
     *
1026
     * @param int    $id
1027
     * @param string $title
1028
     * @param string $description
1029
     * @param $doc_state
1030
     * @param $work_state
1031
     * @param $calendar_state
1032
     * @param $announcements_state
1033
     * @param $forum_state
1034
     * @param $wiki_state
1035
     * @param $chat_state
1036
     * @param $selfRegistrationAllowed
1037
     * @param $selfUnRegistrationAllowed
1038
     * @param $maximum_number_of_students
1039
     * @param $groups_per_user
1040
     * @param $documentAccess
1041
     */
1042
    public static function update_category(
1043
        $id,
1044
        $title,
1045
        $description,
1046
        $doc_state,
1047
        $work_state,
1048
        $calendar_state,
1049
        $announcements_state,
1050
        $forum_state,
1051
        $wiki_state,
1052
        $chat_state,
1053
        $selfRegistrationAllowed,
1054
        $selfUnRegistrationAllowed,
1055
        $maximum_number_of_students,
1056
        $groups_per_user,
1057
        $documentAccess
1058
    ) {
1059
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
1060
        $id = (int) $id;
1061
1062
        $courseId = api_get_course_int_id();
1063
1064
        $allowDocumentAccess = api_get_configuration_value('group_category_document_access');
1065
        $documentCondition = '';
1066
        if ($allowDocumentAccess) {
1067
            $documentAccess = (int) $documentAccess;
1068
            $documentCondition = " document_access = $documentAccess, ";
1069
        }
1070
1071
        $sql = "UPDATE ".$table." SET
1072
                    title='".Database::escape_string($title)."',
1073
                    description='".Database::escape_string($description)."',
1074
                    doc_state = '".Database::escape_string($doc_state)."',
1075
                    work_state = '".Database::escape_string($work_state)."',
1076
                    calendar_state = '".Database::escape_string($calendar_state)."',
1077
                    announcements_state = '".Database::escape_string($announcements_state)."',
1078
                    forum_state = '".Database::escape_string($forum_state)."',
1079
                    wiki_state = '".Database::escape_string($wiki_state)."',
1080
                    chat_state = '".Database::escape_string($chat_state)."',
1081
                    groups_per_user   = '".Database::escape_string($groups_per_user)."',
1082
                    self_reg_allowed = '".Database::escape_string($selfRegistrationAllowed)."',
1083
                    self_unreg_allowed = '".Database::escape_string($selfUnRegistrationAllowed)."',
1084
                    $documentCondition
1085
                    max_student = ".intval($maximum_number_of_students)."
1086
                WHERE c_id = $courseId AND id = $id";
1087
1088
        Database::query($sql);
1089
1090
        // Updating all groups inside this category
1091
        $groups = self::get_group_list($id);
1092
1093
        if (!empty($groups)) {
1094
            foreach ($groups as $group) {
1095
                self::set_group_properties(
1096
                    $group['id'],
1097
                    $group['name'],
1098
                    $group['description'],
1099
                    $maximum_number_of_students,
1100
                    $doc_state,
1101
                    $work_state,
1102
                    $calendar_state,
1103
                    $announcements_state,
1104
                    $forum_state,
1105
                    $wiki_state,
1106
                    $chat_state,
1107
                    $selfRegistrationAllowed,
1108
                    $selfUnRegistrationAllowed,
1109
                    $id,
1110
                    $documentAccess
1111
                );
1112
            }
1113
        }
1114
    }
1115
1116
    /**
1117
     * Returns the number of groups of the user with the greatest number of
1118
     * subscriptions in the given category.
1119
     */
1120
    public static function get_current_max_groups_per_user(
1121
        $category_id = null,
1122
        $course_code = null
1123
    ) {
1124
        $course_info = api_get_course_info($course_code);
1125
        $group_table = Database::get_course_table(TABLE_GROUP);
1126
        $group_user_table = Database::get_course_table(TABLE_GROUP_USER);
1127
        $sql = 'SELECT COUNT(gu.group_id) AS current_max
1128
                FROM '.$group_user_table.' gu, '.$group_table.' g
1129
				WHERE g.c_id = '.$course_info['real_id'].'
1130
				AND gu.c_id = g.c_id
1131
				AND gu.group_id = g.iid ';
1132
        if (null != $category_id) {
1133
            $category_id = intval($category_id);
1134
            $sql .= ' AND g.category_id = '.$category_id;
1135
        }
1136
        $sql .= ' GROUP BY gu.user_id ORDER BY current_max DESC LIMIT 1';
1137
        $res = Database::query($sql);
1138
        $obj = Database::fetch_object($res);
1139
1140
        return $obj->current_max;
1141
    }
1142
1143
    /**
1144
     * Swaps the display-order of two categories.
1145
     *
1146
     * @param int $id1 The id of the first category
1147
     * @param int $id2 The id of the second category
1148
     */
1149
    public static function swap_category_order($id1, $id2)
1150
    {
1151
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
1152
        $id1 = intval($id1);
1153
        $id2 = intval($id2);
1154
        $course_id = api_get_course_int_id();
1155
1156
        $sql = "SELECT id, display_order FROM $table
1157
                WHERE id IN ($id1,$id2) AND c_id = $course_id ";
1158
        $res = Database::query($sql);
1159
        $cat1 = Database::fetch_object($res);
1160
        $cat2 = Database::fetch_object($res);
1161
        if ($cat1 && $cat2) {
1162
            $sql = "UPDATE $table SET display_order=$cat2->display_order
1163
                    WHERE id = $cat1->id AND c_id = $course_id ";
1164
            Database::query($sql);
1165
1166
            $sql = "UPDATE $table SET display_order=$cat1->display_order
1167
                    WHERE id = $cat2->id AND c_id = $course_id ";
1168
            Database::query($sql);
1169
        }
1170
    }
1171
1172
    /**
1173
     * Get all users from a given group.
1174
     *
1175
     * @param int  $group_id        The group
1176
     * @param bool $load_extra_info
1177
     * @param int  $start
1178
     * @param int  $limit
1179
     * @param bool $getCount
1180
     * @param int  $courseId
1181
     * @param $column
1182
     * @param $direction
1183
     *
1184
     * @return array list of user id
1185
     */
1186
    public static function get_users(
1187
        $group_id,
1188
        $load_extra_info = false,
1189
        $start = null,
1190
        $limit = null,
1191
        $getCount = false,
1192
        $courseId = null,
1193
        $column = null,
1194
        $direction = null
1195
    ) {
1196
        $group_user_table = Database::get_course_table(TABLE_GROUP_USER);
1197
        $groupTable = Database::get_course_table(TABLE_GROUP);
1198
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
1199
        $group_id = intval($group_id);
1200
1201
        if (empty($courseId)) {
1202
            $courseId = api_get_course_int_id();
1203
        } else {
1204
            $courseId = intval($courseId);
1205
        }
1206
1207
        $select = " SELECT u.id, firstname, lastname ";
1208
        if ($getCount) {
1209
            $select = " SELECT count(u.id) count";
1210
        }
1211
        $sql = "$select
1212
                FROM $group_user_table gu
1213
                INNER JOIN $groupTable g
1214
                ON (gu.group_id = g.id and g.c_id = gu.c_id)
1215
                INNER JOIN $user_table u
1216
                ON (u.id = gu.user_id)
1217
                WHERE
1218
                    gu.c_id = $courseId AND
1219
                    g.id = $group_id";
1220
1221
        if (!empty($column) && !empty($direction)) {
1222
            $column = Database::escape_string($column, null, false);
1223
            $direction = ('ASC' == $direction ? 'ASC' : 'DESC');
1224
            $sql .= " ORDER BY $column $direction";
1225
        }
1226
1227
        if (!empty($start) && !empty($limit)) {
1228
            $start = (int) $start;
1229
            $limit = (int) $limit;
1230
            $sql .= " LIMIT $start, $limit";
1231
        }
1232
        $res = Database::query($sql);
1233
        $users = [];
1234
        while ($obj = Database::fetch_object($res)) {
1235
            if ($getCount) {
1236
                return $obj->count;
1237
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1238
            }
1239
            if ($load_extra_info) {
1240
                $users[] = api_get_user_info($obj->id);
1241
            } else {
1242
                $users[] = $obj->id;
1243
            }
1244
        }
1245
1246
        return $users;
1247
    }
1248
1249
    /**
1250
     * @param int $group_id id
1251
     *
1252
     * @return array
1253
     */
1254
    public static function getStudentsAndTutors($group_id)
1255
    {
1256
        $group_user_table = Database::get_course_table(TABLE_GROUP_USER);
1257
        $tutor_user_table = Database::get_course_table(TABLE_GROUP_TUTOR);
1258
        $groupTable = Database::get_course_table(TABLE_GROUP);
1259
1260
        $course_id = api_get_course_int_id();
1261
        $group_id = intval($group_id);
1262
        $sql = "SELECT user_id
1263
                FROM $group_user_table gu
1264
                INNER JOIN $groupTable g
1265
                ON (gu.group_id = g.iid and g.c_id = gu.c_id)
1266
                WHERE gu.c_id = $course_id AND g.id = $group_id";
1267
        $res = Database::query($sql);
1268
        $users = [];
1269
1270
        while ($obj = Database::fetch_object($res)) {
1271
            $users[] = api_get_user_info($obj->user_id);
1272
        }
1273
1274
        $sql = "SELECT user_id
1275
                FROM $tutor_user_table gu
1276
                INNER JOIN $groupTable g
1277
                ON (gu.group_id = g.id and g.c_id = gu.c_id)
1278
                WHERE gu.c_id = $course_id AND g.id = $group_id";
1279
        $res = Database::query($sql);
1280
        while ($obj = Database::fetch_object($res)) {
1281
            $users[] = api_get_user_info($obj->user_id);
1282
        }
1283
1284
        return $users;
1285
    }
1286
1287
    /**
1288
     * Get only tutors from a group.
1289
     *
1290
     * @param array $groupInfo
1291
     *
1292
     * @return array
1293
     */
1294
    public static function getTutors($groupInfo)
1295
    {
1296
        $groupTable = Database::get_course_table(TABLE_GROUP);
1297
        $tutor_user_table = Database::get_course_table(TABLE_GROUP_TUTOR);
1298
        $course_id = api_get_course_int_id();
1299
        $group_id = intval($groupInfo['iid']);
1300
1301
        $sql = "SELECT user_id
1302
                FROM $tutor_user_table gu
1303
                INNER JOIN $groupTable g
1304
                ON (gu.group_id = g.id and g.c_id = gu.c_id)
1305
                WHERE gu.c_id = $course_id AND g.iid = $group_id";
1306
        $res = Database::query($sql);
1307
1308
        $users = [];
1309
        while ($obj = Database::fetch_object($res)) {
1310
            $users[] = api_get_user_info($obj->user_id);
1311
        }
1312
1313
        return $users;
1314
    }
1315
1316
    /**
1317
     * Get only students from a group (not tutors).
1318
     *
1319
     * @param int  $group_id         iid
1320
     * @param bool $filterOnlyActive
1321
     *
1322
     * @return array
1323
     */
1324
    public static function getStudents($group_id, $filterOnlyActive = false)
1325
    {
1326
        $activeCondition = $filterOnlyActive ? 'AND u.active = 1' : '';
1327
1328
        $em = Database::getManager();
1329
        $subscriptions = $em
1330
            ->createQuery("
1331
                SELECT u.id FROM ChamiloUserBundle:User u
1332
                INNER JOIN ChamiloCourseBundle:CGroupRelUser gu
1333
                    WITH u.id = gu.userId
1334
                INNER JOIN ChamiloCourseBundle:CGroupInfo g
1335
                WITH gu.groupId = g.id AND g.cId = gu.cId
1336
                WHERE gu.cId = :course AND g.id = :group
1337
                    $activeCondition
1338
            ")
1339
            ->setParameters([
1340
                'course' => api_get_course_int_id(),
1341
                'group' => intval($group_id),
1342
            ])
1343
            ->getResult();
1344
1345
        $users = [];
1346
        /** @var CGroupRelUser $subscription */
1347
        foreach ($subscriptions as $subscription) {
1348
            $users[] = api_get_user_info($subscription['id']);
1349
        }
1350
1351
        return $users;
1352
    }
1353
1354
    /**
1355
     * Returns users belonging to any of the group.
1356
     *
1357
     * @param array $groups list of group ids
1358
     *
1359
     * @return array list of user ids
1360
     */
1361
    public static function get_groups_users($groups = [])
1362
    {
1363
        $result = [];
1364
        $table = Database::get_course_table(TABLE_GROUP_USER);
1365
        $course_id = api_get_course_int_id();
1366
1367
        $groups = array_map('intval', $groups);
1368
        // protect individual elements with surrounding quotes
1369
        $groups = implode(', ', $groups);
1370
        $sql = "SELECT DISTINCT user_id
1371
                FROM $table gu
1372
                WHERE c_id = $course_id AND gu.group_id IN ($groups)";
1373
        $rs = Database::query($sql);
1374
        while ($row = Database::fetch_array($rs)) {
1375
            $result[] = $row['user_id'];
1376
        }
1377
1378
        return $result;
1379
    }
1380
1381
    /**
1382
     * Fill the groups with students.
1383
     * The algorithm takes care to first fill the groups with the least # of users.
1384
     * Analysis
1385
     * There was a problem with the "ALL" setting.
1386
     * When max # of groups is set to all, the value is sometimes NULL and sometimes ALL
1387
     * and in both cased the query does not work as expected.
1388
     * Stupid solution (currently implemented: set ALL to a big number (INFINITE) and things are solved :)
1389
     * Better solution: that's up to you.
1390
     *
1391
     * Note
1392
     * Throughout Dokeos there is some confusion about "course id" and "course code"
1393
     * The code is e.g. TEST101, but sometimes a variable that is called courseID also contains a course code string.
1394
     * However, there is also a integer course_id that uniquely identifies the course.
1395
     * ywarnier:> Now the course_id has been removed (25/1/2005)
1396
     * The databases are als very inconsistent in this.
1397
     *
1398
     * @param array $groupInfo
1399
     *
1400
     * @author Chrisptophe Gesche <[email protected]>,
1401
     *         Hugues Peeters     <[email protected]> - original version
1402
     * @author Roan Embrechts - virtual course support, code cleaning
1403
     * @author Bart Mollet - code cleaning, use other GroupManager-functions
1404
     *
1405
     * @return bool
1406
     */
1407
    public static function fillGroupWithUsers($groupInfo)
1408
    {
1409
        $_course = api_get_course_info();
1410
        if (empty($_course) || empty($groupInfo)) {
1411
            return false;
1412
        }
1413
        $session_id = api_get_session_id();
1414
        $complete_user_list = CourseManager::get_user_list_from_course_code(
1415
            $_course['code'],
1416
            $session_id
1417
        );
1418
        $groupIid = $groupInfo['iid'];
1419
        $category = self::get_category_from_group($groupIid);
1420
1421
        // Getting max numbers of user from group
1422
        $maxNumberStudents = empty($groupInfo['maximum_number_of_students']) ? self::INFINITE : $groupInfo['maximum_number_of_students'];
1423
        $groupsPerUser = self::INFINITE;
1424
        $categoryId = 0;
1425
        if ($category) {
1426
            $groupsPerUser = empty($category['groups_per_user']) ? self::INFINITE : $category['groups_per_user'];
1427
            $maxNumberStudentsCategory = empty($category['max_student']) ? self::INFINITE : $category['max_student'];
1428
            $categoryId = $category['id'];
1429
            if ($maxNumberStudentsCategory < $maxNumberStudents) {
1430
                $maxNumberStudents = $maxNumberStudentsCategory;
1431
            }
1432
        }
1433
1434
        $usersToAdd = [];
1435
        foreach ($complete_user_list as $userInfo) {
1436
            $isSubscribed = self::is_subscribed($userInfo['user_id'], $groupInfo);
1437
            if ($isSubscribed) {
1438
                continue;
1439
            }
1440
            $numberOfGroups = self::user_in_number_of_groups(
1441
                $userInfo['user_id'],
1442
                $categoryId
1443
            );
1444
            if ($groupsPerUser > $numberOfGroups) {
1445
                $usersToAdd[] = $userInfo['user_id'];
1446
            }
1447
            if (count($usersToAdd) == $maxNumberStudents) {
1448
                break;
1449
            }
1450
        }
1451
1452
        foreach ($usersToAdd as $userId) {
1453
            self::subscribe_users($userId, $groupInfo);
1454
        }
1455
    }
1456
1457
    /**
1458
     * Get the number of students in a group.
1459
     *
1460
     * @param int $group_id id
1461
     *
1462
     * @return int number of students in the given group
1463
     */
1464
    public static function number_of_students($group_id, $course_id = null)
1465
    {
1466
        $table = Database::get_course_table(TABLE_GROUP_USER);
1467
        $group_id = (int) $group_id;
1468
        $course_id = (int) $course_id;
1469
1470
        if (empty($course_id)) {
1471
            $course_id = api_get_course_int_id();
1472
        }
1473
        $sql = "SELECT COUNT(*) AS number_of_students
1474
                FROM $table
1475
                WHERE c_id = $course_id AND group_id = $group_id";
1476
        $result = Database::query($sql);
1477
        $db_object = Database::fetch_object($result);
1478
1479
        return $db_object->number_of_students;
1480
    }
1481
1482
    /**
1483
     * Maximum number of students in a group.
1484
     *
1485
     * @param int $group_id iid
1486
     *
1487
     * @return int maximum number of students in the given group
1488
     */
1489
    public static function maximum_number_of_students($group_id)
1490
    {
1491
        $table = Database::get_course_table(TABLE_GROUP);
1492
        $group_id = (int) $group_id;
1493
        $course_id = api_get_course_int_id();
1494
        $sql = "SELECT max_student FROM $table
1495
                WHERE c_id = $course_id AND iid = $group_id";
1496
        $db_result = Database::query($sql);
1497
        $db_object = Database::fetch_object($db_result);
1498
        if (0 == $db_object->max_student) {
1499
            return self::INFINITE;
1500
        }
1501
1502
        return $db_object->max_student;
1503
    }
1504
1505
    /**
1506
     * Number of groups of a user.
1507
     *
1508
     * @param int $user_id
1509
     * @param int $cat_id
1510
     *
1511
     * @return int the number of groups the user is subscribed in
1512
     */
1513
    public static function user_in_number_of_groups($user_id, $cat_id = 0)
1514
    {
1515
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1516
        $table_group = Database::get_course_table(TABLE_GROUP);
1517
        $user_id = (int) $user_id;
1518
        $cat_id = (int) $cat_id;
1519
1520
        $course_id = api_get_course_int_id();
1521
        $cat_condition = '';
1522
        if (!empty($cat_id)) {
1523
            $cat_condition = " AND g.category_id =  $cat_id ";
1524
        }
1525
1526
        $sql = "SELECT COUNT(*) AS number_of_groups
1527
                FROM $table_group_user gu
1528
                INNER JOIN $table_group g
1529
                ON (g.iid = gu.group_id AND gu.c_id = g.c_id)
1530
                WHERE
1531
                    gu.c_id = $course_id AND
1532
                    g.c_id = $course_id AND
1533
                    gu.user_id = $user_id
1534
                    $cat_condition";
1535
1536
        $result = Database::query($sql);
1537
        $db_object = Database::fetch_object($result);
1538
1539
        return $db_object->number_of_groups;
1540
    }
1541
1542
    /**
1543
     * Is sef-registration allowed?
1544
     *
1545
     * @param int   $user_id
1546
     * @param array $groupInfo
1547
     *
1548
     * @return bool TRUE if self-registration is allowed in the given group
1549
     */
1550
    public static function is_self_registration_allowed($user_id, $groupInfo)
1551
    {
1552
        $course_id = api_get_course_int_id();
1553
        if (empty($user_id)) {
1554
            return false;
1555
        }
1556
1557
        $groupIid = $groupInfo['iid'];
1558
        $table = Database::get_course_table(TABLE_GROUP);
1559
        if (isset($groupIid)) {
1560
            $sql = "SELECT status, self_registration_allowed
1561
                    FROM $table
1562
                    WHERE c_id = $course_id AND iid = $groupIid";
1563
            $result = Database::query($sql);
1564
            $group = Database::fetch_object($result);
1565
1566
            if ($group->status == 0 || $group->self_registration_allowed != 1) {
1567
                return false;
1568
            }
1569
1570
            return self::canUserSubscribe($user_id, $groupInfo);
1571
        }
1572
1573
        return false;
1574
    }
1575
1576
    /**
1577
     * Is sef-unregistration allowed?
1578
     *
1579
     * @param int   $user_id
1580
     * @param array $groupInfo
1581
     *
1582
     * @return bool TRUE if self-unregistration is allowed in the given group
1583
     */
1584
    public static function is_self_unregistration_allowed($user_id, $groupInfo)
1585
    {
1586
        if (empty($user_id) || empty($groupInfo)) {
1587
            return false;
1588
        }
1589
        $groupIid = $groupInfo['iid'];
1590
        $table = Database::get_course_table(TABLE_GROUP);
1591
        $course_id = api_get_course_int_id();
1592
1593
        $sql = "SELECT status, self_unregistration_allowed
1594
                FROM $table
1595
                WHERE c_id = $course_id AND iid = $groupIid";
1596
        $result = Database::query($sql);
1597
        $group = Database::fetch_object($result);
1598
1599
        if ($group->status == 0 || $group->self_unregistration_allowed != 1) {
1600
            return false;
1601
        }
1602
1603
        return self::is_subscribed($user_id, $groupInfo);
1604
    }
1605
1606
    /**
1607
     * Is user subscribed in group?
1608
     *
1609
     * @param int   $user_id
1610
     * @param array $groupInfo
1611
     *
1612
     * @return bool TRUE if given user is subscribed in given group
1613
     */
1614
    public static function is_subscribed($user_id, $groupInfo)
1615
    {
1616
        $course_id = api_get_course_int_id();
1617
        if (empty($user_id) || empty($groupInfo) || empty($course_id)) {
1618
            return false;
1619
        }
1620
        $table = Database::get_course_table(TABLE_GROUP_USER);
1621
        $group_id = (int) $groupInfo['id'];
1622
        $user_id = (int) $user_id;
1623
1624
        $sql = "SELECT 1 FROM $table
1625
                WHERE
1626
                    c_id = $course_id AND
1627
                    group_id = $group_id AND
1628
                    user_id = $user_id
1629
                ";
1630
        $result = Database::query($sql);
1631
1632
        return Database::num_rows($result) > 0;
1633
    }
1634
1635
    /**
1636
     * Can a user subscribe to a specified group in a course.
1637
     *
1638
     * @param int   $user_id
1639
     * @param array $groupInfo
1640
     * @param bool  $checkMaxNumberStudents
1641
     *
1642
     * @return bool TRUE if given user  can be subscribed in given group
1643
     */
1644
    public static function canUserSubscribe(
1645
        $user_id,
1646
        $groupInfo,
1647
        $checkMaxNumberStudents = true
1648
    ) {
1649
        $group_id = $groupInfo['id'];
1650
        $groupIid = $groupInfo['iid'];
1651
        if ($checkMaxNumberStudents) {
1652
            $category = self::get_category_from_group($groupIid);
1653
            if ($category) {
1654
                if ($category['groups_per_user'] == self::GROUP_PER_MEMBER_NO_LIMIT) {
1655
                    $category['groups_per_user'] = self::INFINITE;
1656
                }
1657
                $result = self::user_in_number_of_groups($user_id, $category['id']) < $category['groups_per_user'];
1658
                if ($result == false) {
1659
                    return false;
1660
                }
1661
            }
1662
1663
            $result = self::number_of_students($group_id) < self::maximum_number_of_students($groupIid);
1664
1665
            if ($result == false) {
1666
                return false;
1667
            }
1668
        }
1669
1670
        $result = self::is_tutor_of_group($user_id, $groupInfo);
1671
1672
        if ($result) {
1673
            return false;
1674
        }
1675
1676
        $result = self::is_subscribed($user_id, $groupInfo);
1677
1678
        if ($result) {
1679
            return false;
1680
        }
1681
1682
        return true;
1683
    }
1684
1685
    /**
1686
     * Get all subscribed users (members) from a group.
1687
     *
1688
     * @param array $groupInfo
1689
     *
1690
     * @return array An array with information of all users from the given group.
1691
     *               (user_id, firstname, lastname, email)
1692
     */
1693
    public static function get_subscribed_users($groupInfo)
1694
    {
1695
        if (empty($groupInfo)) {
1696
            return [];
1697
        }
1698
1699
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
1700
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1701
        $order_clause = api_sort_by_first_name() ? ' ORDER BY u.firstname, u.lastname' : ' ORDER BY u.lastname, u.firstname';
1702
        $orderListByOfficialCode = api_get_setting('order_user_list_by_official_code');
1703
        if ($orderListByOfficialCode === 'true') {
1704
            $order_clause = ' ORDER BY u.official_code, u.firstname, u.lastname';
1705
        }
1706
1707
        $group_id = (int) $groupInfo['iid'];
1708
1709
        if (empty($group_id)) {
1710
            return [];
1711
        }
1712
1713
        $course_id = api_get_course_int_id();
1714
1715
        $sql = "SELECT
1716
                    ug.id,
1717
                    u.user_id,
1718
                    u.lastname,
1719
                    u.firstname,
1720
                    u.email,
1721
                    u.username
1722
                FROM $table_user u
1723
                INNER JOIN $table_group_user ug
1724
                ON (ug.user_id = u.user_id)
1725
                WHERE ug.c_id = $course_id AND
1726
                      ug.group_id = $group_id
1727
                $order_clause";
1728
1729
        $db_result = Database::query($sql);
1730
        $users = [];
1731
        while ($user = Database::fetch_object($db_result)) {
1732
            $users[$user->user_id] = [
1733
                'user_id' => $user->user_id,
1734
                'firstname' => $user->firstname,
1735
                'lastname' => $user->lastname,
1736
                'email' => $user->email,
1737
                'username' => $user->username,
1738
            ];
1739
        }
1740
1741
        return $users;
1742
    }
1743
1744
    /**
1745
     * @author Patrick Cool <[email protected]>, Ghent University
1746
     * Get all subscribed tutors of a group
1747
     *
1748
     * @param array $groupInfo
1749
     *
1750
     * @return array An array with information of all users from the given group.
1751
     *               (user_id, firstname, lastname, email)
1752
     */
1753
    public static function get_subscribed_tutors($groupInfo, $id_only = false)
1754
    {
1755
        if (empty($groupInfo)) {
1756
            return [];
1757
        }
1758
1759
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
1760
        $table_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
1761
        $order_clause = api_sort_by_first_name() ? ' ORDER BY u.firstname, u.lastname' : ' ORDER BY u.lastname, u.firstname';
1762
1763
        $orderListByOfficialCode = api_get_setting('order_user_list_by_official_code');
1764
        if ($orderListByOfficialCode === 'true') {
1765
            $order_clause = ' ORDER BY u.official_code, u.firstname, u.lastname';
1766
        }
1767
1768
        $group_id = (int) $groupInfo['iid'];
1769
        $course_id = api_get_course_int_id();
1770
1771
        $sql = "SELECT tg.id, u.user_id, u.lastname, u.firstname, u.email
1772
                FROM $table_user u, $table_group_tutor tg
1773
                WHERE
1774
                    tg.c_id = $course_id AND
1775
                    tg.group_id = $group_id AND
1776
                    tg.user_id = u.user_id
1777
                $order_clause
1778
                ";
1779
        $db_result = Database::query($sql);
1780
        $users = [];
1781
        while ($user = Database::fetch_object($db_result)) {
1782
            if (!$id_only) {
1783
                $member['user_id'] = $user->user_id;
1784
                $member['firstname'] = $user->firstname;
1785
                $member['lastname'] = $user->lastname;
1786
                $member['email'] = $user->email;
1787
                $users[] = $member;
1788
            } else {
1789
                $users[] = $user->user_id;
1790
            }
1791
        }
1792
1793
        return $users;
1794
    }
1795
1796
    /**
1797
     * Subscribe user(s) to a specified group in current course (as a student).
1798
     *
1799
     * @param mixed $user_ids  Can be an array with user-id's or a single user-id
1800
     * @param array $groupInfo
1801
     * @param int   $course_id
1802
     *
1803
     * @return bool TRUE if successful
1804
     */
1805
    public static function subscribe_users($user_ids, $groupInfo, $course_id = null)
1806
    {
1807
        $user_ids = is_array($user_ids) ? $user_ids : [$user_ids];
1808
        $course_id = empty($course_id) ? api_get_course_int_id() : (int) $course_id;
1809
        $group_id = $groupInfo['id'];
1810
1811
        if (!empty($user_ids)) {
1812
            $table = Database::get_course_table(TABLE_GROUP_USER);
1813
            foreach ($user_ids as $user_id) {
1814
                if (self::canUserSubscribe($user_id, $groupInfo)) {
1815
                    $user_id = (int) $user_id;
1816
                    $sql = "INSERT INTO ".$table." (c_id, user_id, group_id)
1817
                            VALUES ('$course_id', '".$user_id."', '".$group_id."')";
1818
                    Database::query($sql);
1819
                }
1820
            }
1821
        }
1822
1823
        return true;
1824
    }
1825
1826
    /**
1827
     * Subscribe tutor(s) to a specified group in current course.
1828
     *
1829
     * @param mixed $user_ids  Can be an array with user-id's or a single user-id
1830
     * @param array $groupInfo
1831
     * @param int   $course_id
1832
     *
1833
     * @author Patrick Cool <[email protected]>, Ghent University
1834
     *
1835
     * @see subscribe_users. This function is almost an exact copy of that function.
1836
     *
1837
     * @return bool TRUE if successful
1838
     */
1839
    public static function subscribe_tutors($user_ids, $groupInfo, $course_id = 0)
1840
    {
1841
        $user_ids = is_array($user_ids) ? $user_ids : [$user_ids];
1842
        $result = true;
1843
        $course_id = isset($course_id) && !empty($course_id) ? intval($course_id) : api_get_course_int_id();
1844
        $table_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
1845
        $groupId = (int) $groupInfo['id'];
1846
1847
        foreach ($user_ids as $user_id) {
1848
            $user_id = intval($user_id);
1849
            if (self::canUserSubscribe($user_id, $groupInfo, false)) {
1850
                $sql = "INSERT INTO ".$table_group_tutor." (c_id, user_id, group_id)
1851
                        VALUES ('$course_id', '".$user_id."', '".$groupId."')";
1852
                $result = Database::query($sql);
1853
            }
1854
        }
1855
1856
        return $result;
1857
    }
1858
1859
    /**
1860
     * Unsubscribe user(s) from a specified group in current course.
1861
     *
1862
     * @param mixed $user_ids  Can be an array with user-id's or a single user-id
1863
     * @param array $groupInfo
1864
     *
1865
     * @return bool TRUE if successful
1866
     */
1867
    public static function unsubscribe_users($user_ids, $groupInfo)
1868
    {
1869
        $user_ids = is_array($user_ids) ? $user_ids : [$user_ids];
1870
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1871
        $group_id = intval($groupInfo['id']);
1872
        $course_id = api_get_course_int_id();
1873
        $sql = 'DELETE FROM '.$table_group_user.'
1874
                WHERE
1875
                    c_id = '.$course_id.' AND
1876
                    group_id = '.$group_id.' AND
1877
                    user_id IN ('.implode(',', $user_ids).')
1878
                ';
1879
        Database::query($sql);
1880
    }
1881
1882
    /**
1883
     * Unsubscribe all users from one or more groups.
1884
     *
1885
     * @param array $groupInfo
1886
     *
1887
     * @return bool TRUE if successful
1888
     */
1889
    public static function unsubscribe_all_users($groupInfo)
1890
    {
1891
        $course_id = api_get_course_int_id();
1892
        $groupId = (int) $groupInfo['id'];
1893
        if (empty($course_id) || empty($groupId)) {
1894
            return false;
1895
        }
1896
1897
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1898
        $sql = "DELETE FROM $table_group_user
1899
                WHERE
1900
                    group_id = $groupId AND
1901
                    c_id = $course_id";
1902
        $result = Database::query($sql);
1903
1904
        return $result;
1905
    }
1906
1907
    /**
1908
     * Unsubscribe all tutors from one or more groups.
1909
     *
1910
     * @param int $groupId iid
1911
     *
1912
     * @see unsubscribe_all_users. This function is almost an exact copy of that function.
1913
     *
1914
     * @return bool TRUE if successful
1915
     *
1916
     * @author Patrick Cool <[email protected]>, Ghent University
1917
     */
1918
    public static function unsubscribe_all_tutors($groupId)
1919
    {
1920
        $courseId = api_get_course_int_id();
1921
        $groupId = (int) $groupId;
1922
1923
        if (empty($courseId) || empty($groupId)) {
1924
            return false;
1925
        }
1926
1927
        if (!empty($groupId)) {
1928
            $table_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
1929
            $sql = "DELETE FROM $table_group_tutor
1930
                    WHERE group_id = $groupId AND c_id = $courseId";
1931
            $result = Database::query($sql);
1932
1933
            return $result;
1934
        }
1935
1936
        return true;
1937
    }
1938
1939
    /**
1940
     * Is the user a tutor of this group?
1941
     *
1942
     * @param int   $user_id   the id of the user
1943
     * @param array $groupInfo
1944
     * @param int   $courseId
1945
     *
1946
     * @return bool true/false
1947
     *
1948
     * @todo use the function user_has_access that includes this function
1949
     *
1950
     * @author Patrick Cool <[email protected]>, Ghent University
1951
     */
1952
    public static function is_tutor_of_group($user_id, $groupInfo, $courseId = 0)
1953
    {
1954
        if (empty($groupInfo)) {
1955
            return false;
1956
        }
1957
1958
        $courseId = empty($courseId) ? api_get_course_int_id() : (int) $courseId;
1959
        if (empty($courseId)) {
1960
            return false;
1961
        }
1962
1963
        $user_id = (int) $user_id;
1964
        $group_id = (int) $groupInfo['id'];
1965
1966
        $table = Database::get_course_table(TABLE_GROUP_TUTOR);
1967
1968
        $sql = "SELECT * FROM $table
1969
                WHERE
1970
                    c_id = $courseId AND
1971
                    user_id = $user_id AND
1972
                    group_id = $group_id";
1973
        $result = Database::query($sql);
1974
        if (Database::num_rows($result) > 0) {
1975
            return true;
1976
        }
1977
1978
        return false;
1979
    }
1980
1981
    /**
1982
     * Is the user part of this group? This can be a tutor or a normal member
1983
     * you should use this function if the access to a tool or functionality is
1984
     * restricted to the people who are actually in the group
1985
     * before you had to check if the user was
1986
     * 1. a member of the group OR
1987
     * 2. a tutor of the group. This function combines both.
1988
     *
1989
     * @param int   $user_id   the id of the user
1990
     * @param array $groupInfo
1991
     *
1992
     * @return bool true/false
1993
     *
1994
     * @author Patrick Cool <[email protected]>, Ghent University
1995
     */
1996
    public static function is_user_in_group($user_id, $groupInfo)
1997
    {
1998
        $member = self::is_subscribed($user_id, $groupInfo);
1999
        if ($member) {
2000
            return true;
2001
        }
2002
2003
        $tutor = self::is_tutor_of_group($user_id, $groupInfo);
2004
        if ($tutor) {
2005
            return true;
2006
        }
2007
2008
        return false;
2009
    }
2010
2011
    /**
2012
     * Get all group's from a given course in which a given user is unsubscribed.
2013
     *
2014
     * @author  Patrick Cool
2015
     *
2016
     * @param int $course_id retrieve the groups for
2017
     * @param int $user_id   the ID of the user you want to know all its group memberships
2018
     *
2019
     * @return array
2020
     */
2021
    public static function get_group_ids($course_id, $user_id)
2022
    {
2023
        $groups = [];
2024
        $tbl_group = Database::get_course_table(TABLE_GROUP_USER);
2025
        $tbl_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
2026
        $user_id = intval($user_id);
2027
        $course_id = intval($course_id);
2028
2029
        $sql = "SELECT group_id FROM $tbl_group
2030
                WHERE c_id = $course_id AND user_id = '$user_id'";
2031
        $result = Database::query($sql);
2032
2033
        if ($result) {
2034
            while ($row = Database::fetch_array($result)) {
2035
                $groups[] = $row['group_id'];
2036
            }
2037
        }
2038
2039
        //Also loading if i'm the tutor
2040
        $sql = "SELECT group_id FROM $tbl_group_tutor
2041
                WHERE c_id = $course_id AND user_id = '$user_id'";
2042
        $result = Database::query($sql);
2043
        if ($result) {
2044
            while ($row = Database::fetch_array($result)) {
2045
                $groups[] = $row['group_id'];
2046
            }
2047
        }
2048
        if (!empty($groups)) {
2049
            array_filter($groups);
2050
        }
2051
2052
        return $groups;
2053
    }
2054
2055
    /**
2056
     * Check if a user has access to a certain group tool.
2057
     *
2058
     * @param int    $user_id  The user id
2059
     * @param int    $group_id The group iid
2060
     * @param string $tool     The tool to check the access rights. This should be
2061
     *                         one of constants: GROUP_TOOL_DOCUMENTS
2062
     *
2063
     * @return bool true if the given user has access to the given tool in the
2064
     *              given course
2065
     */
2066
    public static function user_has_access($user_id, $group_id, $tool)
2067
    {
2068
        // Admin have access everywhere
2069
        if (api_is_platform_admin()) {
2070
            return true;
2071
        }
2072
2073
        // Course admin also have access to everything
2074
        if (api_is_allowed_to_edit(false, true, true)) {
2075
            return true;
2076
        }
2077
2078
        switch ($tool) {
2079
            case self::GROUP_TOOL_FORUM:
2080
                $key = 'forum_state';
2081
                break;
2082
            case self::GROUP_TOOL_DOCUMENTS:
2083
                $key = 'doc_state';
2084
                break;
2085
            case self::GROUP_TOOL_CALENDAR:
2086
                $key = 'calendar_state';
2087
                break;
2088
            case self::GROUP_TOOL_ANNOUNCEMENT:
2089
                $key = 'announcements_state';
2090
                break;
2091
            case self::GROUP_TOOL_WORK:
2092
                $key = 'work_state';
2093
                break;
2094
            case self::GROUP_TOOL_WIKI:
2095
                $key = 'wiki_state';
2096
                break;
2097
            case self::GROUP_TOOL_CHAT:
2098
                $key = 'chat_state';
2099
                break;
2100
            default:
2101
                return false;
2102
        }
2103
2104
        // Check group properties
2105
        $groupInfo = self::get_group_properties($group_id, true);
2106
2107
        if (empty($groupInfo)) {
2108
            return false;
2109
        }
2110
2111
        if ($groupInfo['status'] == 0) {
2112
            return false;
2113
        }
2114
2115
        if (!isset($groupInfo[$key])) {
2116
            return false;
2117
        }
2118
2119
        $status = $groupInfo[$key];
2120
2121
        switch ($status) {
2122
            case self::TOOL_NOT_AVAILABLE:
2123
                return false;
2124
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
2125
            case self::TOOL_PUBLIC:
2126
                return true;
2127
                break;
2128
            case self::TOOL_PRIVATE:
2129
                $userIsInGroup = self::is_user_in_group($user_id, $groupInfo);
2130
                if ($userIsInGroup) {
2131
                    return true;
2132
                }
2133
                break;
2134
            case self::TOOL_PRIVATE_BETWEEN_USERS:
2135
                // Only works for announcements for now
2136
                $userIsInGroup = self::is_user_in_group($user_id, $groupInfo);
2137
                if ($userIsInGroup && $tool == self::GROUP_TOOL_ANNOUNCEMENT) {
2138
                    return true;
2139
                }
2140
                break;
2141
        }
2142
2143
        return false;
2144
    }
2145
2146
    /**
2147
     * @param int   $userId
2148
     * @param array $groupInfo
2149
     * @param int   $sessionId
2150
     *
2151
     * @return bool
2152
     */
2153
    public static function userHasAccessToBrowse($userId, $groupInfo, $sessionId = 0)
2154
    {
2155
        if (empty($groupInfo)) {
2156
            return false;
2157
        }
2158
2159
        if (api_is_platform_admin()) {
2160
            return true;
2161
        }
2162
2163
        if (api_is_allowed_to_edit(false, true, true)) {
2164
            return true;
2165
        }
2166
2167
        if (!empty($sessionId)) {
2168
            if (api_is_coach($sessionId, api_get_course_int_id())) {
2169
                return true;
2170
            }
2171
2172
            if (api_is_drh()) {
2173
                if (SessionManager::isUserSubscribedAsHRM($sessionId, $userId)) {
2174
                    return true;
2175
                }
2176
            }
2177
        }
2178
2179
        $groupId = $groupInfo['iid'];
2180
        if (self::is_tutor_of_group($userId, $groupInfo)) {
2181
            return true;
2182
        }
2183
2184
        if ($groupInfo['status'] == 0) {
2185
            return false;
2186
        }
2187
2188
        if (self::user_has_access($userId, $groupId, self::GROUP_TOOL_FORUM) ||
2189
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_DOCUMENTS) ||
2190
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_CALENDAR) ||
2191
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_ANNOUNCEMENT) ||
2192
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_WORK) ||
2193
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_WIKI) ||
2194
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_CHAT)
2195
        ) {
2196
            return true;
2197
        }
2198
2199
        if (api_is_session_general_coach() && $groupInfo['session_id'] == $sessionId) {
2200
            return true;
2201
        }
2202
2203
        return false;
2204
    }
2205
2206
    /**
2207
     * Get all groups where a specific user is subscribed.
2208
     *
2209
     * @param int $user_id
2210
     *
2211
     * @return array
2212
     */
2213
    public static function get_user_group_name($user_id)
2214
    {
2215
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
2216
        $table_group = Database::get_course_table(TABLE_GROUP);
2217
        $user_id = intval($user_id);
2218
        $course_id = api_get_course_int_id();
2219
        $sql = "SELECT name
2220
                FROM $table_group g
2221
                INNER JOIN $table_group_user gu
2222
                ON (gu.group_id = g.iid)
2223
                WHERE
2224
                  gu.c_id= $course_id AND
2225
                  g.c_id= $course_id AND
2226
                  gu.user_id = $user_id";
2227
        $res = Database::query($sql);
2228
        $groups = [];
2229
        while ($group = Database::fetch_array($res)) {
2230
            $groups[] .= $group['name'];
2231
        }
2232
2233
        return $groups;
2234
    }
2235
2236
    /**
2237
     * Get all groups where a specific user is subscribed.
2238
     *
2239
     * @param int      $user_id
2240
     * @param int      $courseId
2241
     * @param int|null $sessionId
2242
     *
2243
     * @return array
2244
     */
2245
    public static function getAllGroupPerUserSubscription($user_id, $courseId = 0, $sessionId = null)
2246
    {
2247
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
2248
        $table_tutor_user = Database::get_course_table(TABLE_GROUP_TUTOR);
2249
        $table_group = Database::get_course_table(TABLE_GROUP);
2250
        $user_id = (int) $user_id;
2251
        $courseId = empty($courseId) ? api_get_course_int_id() : (int) $courseId;
2252
2253
        $sql = "SELECT DISTINCT g.*
2254
               FROM $table_group g
2255
               LEFT JOIN $table_group_user gu
2256
               ON (gu.group_id = g.iid AND g.c_id = gu.c_id)
2257
               LEFT JOIN $table_tutor_user tu
2258
               ON (tu.group_id = g.iid AND g.c_id = tu.c_id)
2259
               WHERE
2260
                  g.c_id = $courseId AND
2261
                  (gu.user_id = $user_id OR tu.user_id = $user_id) ";
2262
2263
        if (null !== $sessionId) {
2264
            $sessionId = (int) $sessionId;
2265
            $sql .= " AND g.session_id = $sessionId ";
2266
        }
2267
2268
        $res = Database::query($sql);
2269
        $groups = [];
2270
        while ($group = Database::fetch_array($res, 'ASSOC')) {
2271
            $groups[] = $group;
2272
        }
2273
2274
        return $groups;
2275
    }
2276
2277
    /**
2278
     * @param array $group_list
2279
     * @param int   $category_id
2280
     *
2281
     * @return string
2282
     */
2283
    public static function process_groups($group_list, $category_id = 0)
2284
    {
2285
        $charset = 'UTF-8';
2286
        $category_id = (int) $category_id;
2287
        $totalRegistered = 0;
2288
        $group_data = [];
2289
        $user_info = api_get_user_info();
2290
        $session_id = api_get_session_id();
2291
        $user_id = $user_info['user_id'];
2292
        $hideGroup = api_get_setting('hide_course_group_if_no_tools_available');
2293
        $extraField = new ExtraField('survey');
2294
        $surveyGroupExists = $extraField->get_handler_field_info_by_field_variable('group_id') ? true : false;
2295
        $url = api_get_path(WEB_CODE_PATH).'group/';
2296
2297
        foreach ($group_list as $this_group) {
2298
            // Validation when belongs to a session
2299
            $session_img = api_get_session_image($this_group['session_id'], $user_info['status']);
2300
2301
            // All the tutors of this group
2302
            $tutors = self::get_subscribed_tutors($this_group, true);
2303
            $isMember = self::is_subscribed($user_id, $this_group);
2304
2305
            // Create a new table-row
2306
            $row = [];
2307
            // Checkbox
2308
            if (api_is_allowed_to_edit(false, true) && count($group_list) > 1) {
2309
                $row[] = $this_group['id'];
2310
            }
2311
2312
            if (self::userHasAccessToBrowse($user_id, $this_group, $session_id)) {
2313
                // Group name
2314
                $groupNameClass = null;
2315
                if (0 == $this_group['status']) {
2316
                    $groupNameClass = 'muted';
2317
                }
2318
2319
                $group_name = '<a class="'.$groupNameClass.'" href="group_space.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'">'.
2320
                    Security::remove_XSS($this_group['name']).'</a> ';
2321
2322
                $group_name2 = '';
2323
                if (api_get_configuration_value('extra')) {
2324
                    $group_name2 = '<a href="group_space_tracking.php?cidReq='.api_get_course_id().'&gidReq='
2325
                        .$this_group['id'].'">'.get_lang('suivi_de').''.stripslashes($this_group['name']).'</a>';
2326
                }
2327
2328
                if (!empty($user_id) && !empty($this_group['id_tutor']) && $user_id == $this_group['id_tutor']) {
2329
                    $group_name .= Display::label(get_lang('OneMyGroups'), 'success');
2330
                } elseif ($isMember) {
2331
                    $group_name .= Display::label(get_lang('MyGroup'), 'success');
2332
                }
2333
2334
                if (api_is_allowed_to_edit() && !empty($this_group['session_name'])) {
2335
                    $group_name .= ' ('.$this_group['session_name'].')';
2336
                }
2337
                $group_name .= $session_img;
2338
                $row[] = $group_name.$group_name2.'<br />'.stripslashes(trim($this_group['description']));
2339
            } else {
2340
                if ('true' === $hideGroup) {
2341
                    continue;
2342
                }
2343
                $row[] = $this_group['name'].'<br />'.stripslashes(trim($this_group['description']));
2344
            }
2345
2346
            // Tutor name
2347
            $tutor_info = '';
2348
            if (count($tutors) > 0) {
2349
                foreach ($tutors as $tutor_id) {
2350
                    $tutor = api_get_user_info($tutor_id);
2351
                    $username = api_htmlentities(
2352
                        sprintf(get_lang('LoginX'), $tutor['username']),
2353
                        ENT_QUOTES
2354
                    );
2355
                    if ('true' === api_get_setting('show_email_addresses')) {
2356
                        $tutor_info .= Display::tag(
2357
                            'span',
2358
                            Display::encrypted_mailto_link(
2359
                                $tutor['mail'],
2360
                                $tutor['complete_name']
2361
                            ),
2362
                            ['title' => $username]
2363
                        ).', ';
2364
                    } else {
2365
                        if (api_is_allowed_to_edit()) {
2366
                            $tutor_info .= Display::tag(
2367
                            'span',
2368
                                Display::encrypted_mailto_link(
2369
                                    $tutor['mail'],
2370
                                    $tutor['complete_name_with_username']
2371
                                ),
2372
                                ['title' => $username]
2373
                            ).', ';
2374
                        } else {
2375
                            $tutor_info .= Display::tag(
2376
                                'span',
2377
                                $tutor['complete_name'],
2378
                                ['title' => $username]
2379
                            ).', ';
2380
                        }
2381
                    }
2382
                }
2383
            }
2384
2385
            $tutor_info = api_substr(
2386
                $tutor_info,
2387
                0,
2388
                api_strlen($tutor_info) - 2
2389
            );
2390
            $row[] = $tutor_info;
2391
2392
            // Max number of members in group
2393
            $max_members = $this_group['maximum_number_of_members'] == self::MEMBER_PER_GROUP_NO_LIMIT ? ' ' : ' / '.$this_group['maximum_number_of_members'];
2394
2395
            // Number of members in group
2396
            $row[] = $this_group['number_of_members'].$max_members;
2397
2398
            // Self-registration / unregistration
2399
            if (!api_is_allowed_to_edit(false, true)) {
2400
                if (self::is_self_registration_allowed($user_id, $this_group)) {
2401
                    $row[] = '<a class = "btn btn-default"
2402
                        href="group.php?'.api_get_cidreq().'&category='.$category_id.'&action=self_reg&group_id='.$this_group['id'].'"
2403
                        onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES, $charset))."'".')) return false;">'.get_lang('GroupSelfRegInf').'</a>';
2404
                } elseif (self::is_self_unregistration_allowed($user_id, $this_group)) {
2405
                    $row[] = '<a class = "btn btn-default"
2406
                        href="group.php?'.api_get_cidreq().'&category='.$category_id.'&action=self_unreg&group_id='.$this_group['id'].'"
2407
                        onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES, $charset))."'".')) return false;">'.get_lang('GroupSelfUnRegInf').'</a>';
2408
                } else {
2409
                    $row[] = '-';
2410
                }
2411
            }
2412
2413
            // Edit-links
2414
            if (api_is_allowed_to_edit(false, true) &&
2415
                !(api_is_session_general_coach() && intval($this_group['session_id']) != $session_id)
2416
            ) {
2417
                $edit_actions = '<a href="'.$url.'settings.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'" title="'.get_lang('Edit').'">'.
2418
                    Display::return_icon('edit.png', get_lang('EditGroup'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2419
2420
                if ($this_group['status'] == 1) {
2421
                    $edit_actions .= '<a href="'.api_get_self().'?'.api_get_cidreq(true, false).'&category='.$category_id.'&action=set_invisible&id='.$this_group['id'].'" title="'.get_lang('Hide').'">'.
2422
                        Display::return_icon('visible.png', get_lang('Hide'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2423
                } else {
2424
                    $edit_actions .= '<a href="'.api_get_self().'?'.api_get_cidreq(true, false).'&category='.$category_id.'&action=set_visible&id='.$this_group['id'].'" title="'.get_lang('Show').'">'.
2425
                        Display::return_icon('invisible.png', get_lang('Show'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2426
                }
2427
2428
                $edit_actions .= '<a href="'.$url.'member_settings.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'" title="'.get_lang('GroupMembers').'">'.
2429
                    Display::return_icon('user.png', get_lang('GroupMembers'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2430
2431
                $edit_actions .= '<a href="'.$url.'group_overview.php?action=export&type=xls&'.api_get_cidreq(true, false).'&id='.$this_group['id'].'" title="'.get_lang('ExportUsers').'">'.
2432
                    Display::return_icon('export_excel.png', get_lang('Export'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2433
2434
                if ($surveyGroupExists) {
2435
                    $edit_actions .= Display::url(
2436
                            Display::return_icon('survey.png', get_lang('ExportSurveyResults'), '', ICON_SIZE_SMALL),
2437
                            $url.'group_overview.php?action=export_surveys&'.api_get_cidreq(true, false).'&id='.$this_group['id']
2438
                        ).'&nbsp;';
2439
                }
2440
                $edit_actions .= '<a href="'.api_get_self().'?'.api_get_cidreq(true, false).'&category='.$category_id.'&action=fill_one&id='.$this_group['id'].'"
2441
                    onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;" title="'.get_lang('FillGroup').'">'.
2442
                    Display::return_icon('fill.png', get_lang('FillGroup'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2443
2444
                $edit_actions .= '<a href="'.api_get_self().'?'.api_get_cidreq(true, false).'&category='.$category_id.'&action=delete_one&id='.$this_group['id'].'"
2445
                    onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;" title="'.get_lang('Delete').'">'.
2446
                    Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2447
2448
                $row[] = $edit_actions;
2449
            }
2450
            if (!empty($this_group['nbMember'])) {
2451
                $totalRegistered = $totalRegistered + $this_group['nbMember'];
2452
            }
2453
            $group_data[] = $row;
2454
        }
2455
2456
        // If no groups then don't show the table (only for students)
2457
        if (!api_is_allowed_to_edit(true, false)) {
2458
            if (empty($group_data)) {
2459
                return '';
2460
            }
2461
        }
2462
2463
        $table = new SortableTableFromArrayConfig(
2464
            $group_data,
2465
            1,
2466
            20,
2467
            'group_category_'.$category_id
2468
        );
2469
        $table->set_additional_parameters(['category' => $category_id]);
2470
        $column = 0;
2471
        if (api_is_allowed_to_edit(false, true) and count($group_list) > 1) {
2472
            $table->set_header($column++, '', false);
2473
        }
2474
        $table->set_header($column++, get_lang('Groups'));
2475
        $table->set_header($column++, get_lang('GroupTutor'));
2476
        $table->set_header($column++, get_lang('Registered'), false);
2477
2478
        if (!api_is_allowed_to_edit(false, true)) {
2479
            // If self-registration allowed
2480
            $table->set_header($column++, get_lang('GroupSelfRegistration'), false);
2481
        }
2482
2483
        if (api_is_allowed_to_edit(false, true)) {
2484
            // Only for course administrator
2485
            $table->set_header($column++, get_lang('Modify'), false);
2486
            $form_actions = [];
2487
            $form_actions['fill_selected'] = get_lang('FillGroup');
2488
            $form_actions['empty_selected'] = get_lang('EmptyGroup');
2489
            $form_actions['delete_selected'] = get_lang('Delete');
2490
            if (count($group_list) > 1) {
2491
                $table->set_form_actions($form_actions, 'group');
2492
            }
2493
        }
2494
2495
        return $table->return_table();
2496
    }
2497
2498
    /**
2499
     * @param array $groupData
2500
     * @param bool  $deleteNotInArray
2501
     *
2502
     * @return array
2503
     */
2504
    public static function importCategoriesAndGroupsFromArray(
2505
        $groupData,
2506
        $deleteNotInArray = false
2507
    ) {
2508
        $result = [];
2509
        $elementsFound = [
2510
            'categories' => [],
2511
            'groups' => [],
2512
        ];
2513
2514
        $courseCode = api_get_course_id();
2515
        $sessionId = api_get_session_id();
2516
        $groupCategories = self::get_categories();
2517
2518
        if (empty($groupCategories)) {
2519
            $result['error'][] = get_lang('CreateACategory');
2520
2521
            return $result;
2522
        }
2523
2524
        foreach ($groupData as $data) {
2525
            $isCategory = empty($data['group']) ? true : false;
2526
            if ($isCategory) {
2527
                $categoryInfo = self::getCategoryByTitle($data['category']);
2528
                $categoryId = $categoryInfo['id'];
2529
2530
                if (!empty($categoryInfo)) {
2531
                    // Update
2532
                    self::update_category(
2533
                        $categoryId,
2534
                        $data['category'],
2535
                        $data['description'],
2536
                        $data['doc_state'],
2537
                        $data['work_state'],
2538
                        $data['calendar_state'],
2539
                        $data['announcements_state'],
2540
                        $data['forum_state'],
2541
                        $data['wiki_state'],
2542
                        $data['chat_state'],
2543
                        $data['self_reg_allowed'],
2544
                        $data['self_unreg_allowed'],
2545
                        $data['max_student'],
2546
                        $data['groups_per_user'],
2547
                        isset($data['document_access']) ? $data['document_access'] : null
2548
                    );
2549
                    $data['category_id'] = $categoryId;
2550
                    $result['updated']['category'][] = $data;
2551
                } else {
2552
                    // Add
2553
                    $categoryId = self::create_category(
2554
                        $data['category'],
2555
                        $data['description'],
2556
                        $data['doc_state'],
2557
                        $data['work_state'],
2558
                        $data['calendar_state'],
2559
                        $data['announcements_state'],
2560
                        $data['forum_state'],
2561
                        $data['wiki_state'],
2562
                        $data['chat_state'],
2563
                        $data['self_reg_allowed'],
2564
                        $data['self_unreg_allowed'],
2565
                        $data['max_student'],
2566
                        $data['groups_per_user']
2567
                    );
2568
2569
                    if ($categoryId) {
2570
                        $data['category_id'] = $categoryId;
2571
                        $result['added']['category'][] = $data;
2572
                    }
2573
                }
2574
                $elementsFound['categories'][] = $categoryId;
2575
            } else {
2576
                $groupInfo = self::getGroupByName($data['group']);
2577
                $categoryInfo = [];
2578
                if (isset($data['category'])) {
2579
                    $categoryInfo = self::getCategoryByTitle($data['category']);
2580
                }
2581
                $categoryId = null;
2582
                if (!empty($categoryInfo)) {
2583
                    $categoryId = $categoryInfo['id'];
2584
                } else {
2585
                    if (!empty($groupCategories) && isset($groupCategories[0])) {
2586
                        $defaultGroupCategory = $groupCategories[0];
2587
                        $categoryId = $defaultGroupCategory['id'];
2588
                    }
2589
                }
2590
2591
                if (empty($groupInfo)) {
2592
                    // Add
2593
                    $groupId = self::create_group(
2594
                        $data['group'],
2595
                        $categoryId,
2596
                        null,
2597
                        $data['max_student']
2598
                    );
2599
2600
                    if ($groupId) {
2601
                        self::set_group_properties(
2602
                            $groupId,
2603
                            $data['group'],
2604
                            $data['description'],
2605
                            $data['max_student'],
2606
                            $data['doc_state'],
2607
                            $data['work_state'],
2608
                            $data['calendar_state'],
2609
                            $data['announcements_state'],
2610
                            $data['forum_state'],
2611
                            $data['wiki_state'],
2612
                            $data['chat_state'],
2613
                            $data['self_reg_allowed'],
2614
                            $data['self_unreg_allowed'],
2615
                            $categoryId
2616
                        );
2617
                        $data['group_id'] = $groupId;
2618
                        $result['added']['group'][] = $data;
2619
                    }
2620
                    $groupInfo = self::get_group_properties($groupId, true);
2621
                } else {
2622
                    // Update
2623
                    $groupId = $groupInfo['id'];
2624
                    self::set_group_properties(
2625
                        $groupId,
2626
                        $data['group'],
2627
                        $data['description'],
2628
                        $data['max_student'],
2629
                        $data['doc_state'],
2630
                        $data['work_state'],
2631
                        $data['calendar_state'],
2632
                        $data['announcements_state'],
2633
                        $data['forum_state'],
2634
                        $data['wiki_state'],
2635
                        $data['chat_state'],
2636
                        $data['self_reg_allowed'],
2637
                        $data['self_unreg_allowed'],
2638
                        $categoryId
2639
                    );
2640
2641
                    $data['group_id'] = $groupId;
2642
                    $result['updated']['group'][] = $data;
2643
                    $groupInfo = self::get_group_properties($groupId);
2644
                }
2645
2646
                $students = isset($data['students']) ? explode(',', $data['students']) : [];
2647
                if (!empty($students)) {
2648
                    $studentUserIdList = [];
2649
                    foreach ($students as $student) {
2650
                        $userInfo = api_get_user_info_from_username($student);
2651
2652
                        if (!$userInfo) {
2653
                            continue;
2654
                        }
2655
2656
                        if (!CourseManager::is_user_subscribed_in_course(
2657
                                $userInfo['user_id'],
2658
                                $courseCode,
2659
                                !empty($sessionId),
2660
                                $sessionId
2661
                            )
2662
                        ) {
2663
                            Display::addFlash(
2664
                                Display::return_message(
2665
                                    sprintf(
2666
                                        get_lang('StudentXIsNotSubscribedToCourse'),
2667
                                        $userInfo['complete_name']
2668
                                    ),
2669
                                    'warning'
2670
                                )
2671
                            );
2672
                            continue;
2673
                        }
2674
2675
                        $studentUserIdList[] = $userInfo['user_id'];
2676
                    }
2677
                    self::subscribe_users($studentUserIdList, $groupInfo);
2678
                }
2679
2680
                $tutors = isset($data['tutors']) ? explode(',', $data['tutors']) : [];
2681
                if (!empty($tutors)) {
2682
                    $tutorIdList = [];
2683
                    foreach ($tutors as $tutor) {
2684
                        $userInfo = api_get_user_info_from_username($tutor);
2685
2686
                        if (!$userInfo) {
2687
                            continue;
2688
                        }
2689
2690
                        if (!CourseManager::is_user_subscribed_in_course(
2691
                                $userInfo['user_id'],
2692
                                $courseCode,
2693
                                !empty($sessionId),
2694
                                $sessionId
2695
                            )
2696
                        ) {
2697
                            Display::addFlash(
2698
                                Display::return_message(
2699
                                    sprintf(get_lang('TutorXIsNotSubscribedToCourse'), $userInfo['complete_name']),
2700
                                    'warning'
2701
                                )
2702
                            );
2703
2704
                            continue;
2705
                        }
2706
2707
                        $tutorIdList[] = $userInfo['user_id'];
2708
                    }
2709
                    self::subscribe_tutors($tutorIdList, $groupInfo);
2710
                }
2711
2712
                $elementsFound['groups'][] = $groupId;
2713
            }
2714
        }
2715
2716
        if ($deleteNotInArray) {
2717
            // Check categories
2718
            $categories = self::get_categories();
2719
            foreach ($categories as $category) {
2720
                if (!in_array($category['id'], $elementsFound['categories'])) {
2721
                    self::delete_category($category['id']);
2722
                    $category['category'] = $category['title'];
2723
                    $result['deleted']['category'][] = $category;
2724
                }
2725
            }
2726
2727
            $groups = self::get_groups();
2728
            foreach ($groups as $group) {
2729
                if (!in_array($group['iid'], $elementsFound['groups'])) {
2730
                    self::deleteGroup($group);
2731
                    $group['group'] = $group['name'];
2732
                    $result['deleted']['group'][] = $group;
2733
                }
2734
            }
2735
        }
2736
2737
        return $result;
2738
    }
2739
2740
    /**
2741
     * Export all categories/group from a course to an array.
2742
     * This function works only in a context of a course.
2743
     *
2744
     * @param int  $groupId
2745
     * @param bool $loadUsers
2746
     *
2747
     * @return array
2748
     */
2749
    public static function exportCategoriesAndGroupsToArray($groupId = null, $loadUsers = false)
2750
    {
2751
        $data = [];
2752
        $data[] = [
2753
            'category',
2754
            'group',
2755
            'description',
2756
            'announcements_state',
2757
            'calendar_state',
2758
            'chat_state',
2759
            'doc_state',
2760
            'forum_state',
2761
            'work_state',
2762
            'wiki_state',
2763
            'max_student',
2764
            'self_reg_allowed',
2765
            'self_unreg_allowed',
2766
            'groups_per_user',
2767
        ];
2768
2769
        $count = 1;
2770
2771
        if ($loadUsers) {
2772
            $data[0][] = 'students';
2773
            $data[0][] = 'tutors';
2774
        }
2775
2776
        if (false == $loadUsers) {
2777
            $categories = self::get_categories();
2778
2779
            foreach ($categories as $categoryInfo) {
2780
                $data[$count] = [
2781
                    $categoryInfo['title'],
2782
                    null,
2783
                    $categoryInfo['description'],
2784
                    $categoryInfo['announcements_state'],
2785
                    $categoryInfo['calendar_state'],
2786
                    $categoryInfo['chat_state'],
2787
                    $categoryInfo['doc_state'],
2788
                    $categoryInfo['forum_state'],
2789
                    $categoryInfo['work_state'],
2790
                    $categoryInfo['wiki_state'],
2791
                    $categoryInfo['max_student'],
2792
                    $categoryInfo['self_reg_allowed'],
2793
                    $categoryInfo['self_unreg_allowed'],
2794
                    $categoryInfo['groups_per_user'],
2795
                ];
2796
                $count++;
2797
            }
2798
        }
2799
2800
        $groups = self::get_group_list();
2801
2802
        foreach ($groups as $groupInfo) {
2803
            $categoryTitle = null;
2804
            $categoryInfo = self::get_category($groupInfo['category_id']);
2805
            $groupSettings = self::get_group_properties($groupInfo['id']);
2806
            if (!empty($categoryInfo)) {
2807
                $categoryTitle = $categoryInfo['title'];
2808
            }
2809
2810
            $users = self::getStudents($groupInfo['iid']);
2811
            $userList = [];
2812
            foreach ($users as $user) {
2813
                $user = api_get_user_info($user['user_id']);
2814
                $userList[] = $user['username'];
2815
            }
2816
2817
            $tutors = self::getTutors($groupInfo);
2818
            $tutorList = [];
2819
            foreach ($tutors as $user) {
2820
                $user = api_get_user_info($user['user_id']);
2821
                $tutorList[] = $user['username'];
2822
            }
2823
2824
            $userListToString = null;
2825
            if (!empty($userList)) {
2826
                $userListToString = implode(',', $userList);
2827
            }
2828
2829
            $tutorListToString = null;
2830
            if (!empty($tutorList)) {
2831
                $tutorListToString = implode(',', $tutorList);
2832
            }
2833
2834
            $data[$count] = [
2835
                $categoryTitle,
2836
                $groupSettings['name'],
2837
                $groupSettings['description'],
2838
                $groupSettings['announcements_state'],
2839
                $groupSettings['calendar_state'],
2840
                $groupSettings['chat_state'],
2841
                $groupSettings['doc_state'],
2842
                $groupSettings['forum_state'],
2843
                $groupSettings['work_state'],
2844
                $groupSettings['wiki_state'],
2845
                $groupSettings['maximum_number_of_students'],
2846
                $groupSettings['self_registration_allowed'],
2847
                $groupSettings['self_unregistration_allowed'],
2848
                null,
2849
            ];
2850
2851
            if ($loadUsers) {
2852
                $data[$count][] = $userListToString;
2853
                $data[$count][] = $tutorListToString;
2854
            }
2855
2856
            if (!empty($groupId)) {
2857
                if ($groupId == $groupInfo['id']) {
2858
                    break;
2859
                }
2860
            }
2861
            $count++;
2862
        }
2863
2864
        return $data;
2865
    }
2866
2867
    /**
2868
     * @param string $default
2869
     */
2870
    public static function getSettingBar($default)
2871
    {
2872
        $activeSettings = null;
2873
        $activeTutor = null;
2874
        $activeMember = null;
2875
2876
        switch ($default) {
2877
            case 'settings':
2878
                $activeSettings = 'active';
2879
                break;
2880
            case'tutor':
2881
                $activeTutor = 'active';
2882
                break;
2883
            case 'member':
2884
                $activeMember = 'active';
2885
                break;
2886
        }
2887
2888
        $url = api_get_path(WEB_CODE_PATH).'group/%s?'.api_get_cidreq();
2889
2890
        echo '
2891
            <ul class="toolbar-groups nav nav-tabs">
2892
                <li class="'.$activeSettings.'">
2893
                    <a id="group_settings_tab" href="'.sprintf($url, 'settings.php').'">
2894
                    '.Display::return_icon('settings.png').' '.get_lang('Settings').'
2895
                    </a>
2896
                </li>
2897
                <li class="'.$activeMember.'">
2898
                    <a id="group_members_tab" href="'.sprintf($url, 'member_settings.php').'">
2899
                    '.Display::return_icon('user.png').' '.get_lang('GroupMembers').'</a>
2900
                </li>
2901
                <li class="'.$activeTutor.'">
2902
                    <a id="group_tutors_tab" href="'.sprintf($url, 'tutor_settings.php').'">
2903
                    '.Display::return_icon('teacher.png').' '.get_lang('GroupTutors').'
2904
                    </a>
2905
                </li>
2906
            </ul>';
2907
    }
2908
2909
    public static function groupOverview($group, $url)
2910
    {
2911
        $groupId = $group['id'];
2912
        $content = '<li>';
2913
        $content .= Display::tag(
2914
            'h3',
2915
            Display::url(
2916
                Security::remove_XSS($group['name']),
2917
                $url.'&gidReq='.$groupId
2918
            )
2919
        );
2920
        $users = self::getTutors($group);
2921
        if (!empty($users)) {
2922
            $content .= '<ul>';
2923
            $content .= "<li>".Display::tag('h4', get_lang('Tutors'))."</li><ul>";
2924
            foreach ($users as $user) {
2925
                $userInfo = api_get_user_info($user['user_id']);
2926
                $content .= '<li title="'.$userInfo['username'].'">'.
2927
                    $userInfo['complete_name_with_username'].
2928
                    '</li>';
2929
            }
2930
            $content .= '</ul>';
2931
            $content .= '</ul>';
2932
        }
2933
2934
        $users = self::getStudents($group['id']);
2935
        if (!empty($users)) {
2936
            $content .= '<ul>';
2937
            $content .= "<li>".Display::tag('h4', get_lang('Students'))."</li><ul>";
2938
            foreach ($users as $user) {
2939
                $userInfo = api_get_user_info($user['user_id']);
2940
                $content .= '<li title="'.$userInfo['username'].'">'.
2941
                    $userInfo['complete_name_with_username'].
2942
                    '</li>';
2943
            }
2944
            $content .= '</ul>';
2945
            $content .= '</ul>';
2946
        }
2947
        $content .= '</li>';
2948
2949
        return $content;
2950
    }
2951
2952
    /**
2953
     * @param int    $courseId
2954
     * @param string $keyword
2955
     *
2956
     * @return string
2957
     */
2958
    public static function getOverview($courseId, $keyword = '')
2959
    {
2960
        $content = null;
2961
        $categories = self::get_categories();
2962
        $url = api_get_path(WEB_CODE_PATH).'group/group_space.php?'.api_get_cidreq(true, false);
2963
        if (!empty($categories)) {
2964
            foreach ($categories as $category) {
2965
                if ('true' === api_get_setting('allow_group_categories')) {
2966
                    $content .= '<h2>'.$category['title'].'</h2>';
2967
                }
2968
2969
                if (!empty($keyword)) {
2970
                    $groups = self::getGroupListFilterByName(
2971
                        $keyword,
2972
                        $category['id'],
2973
                        $courseId
2974
                    );
2975
                } else {
2976
                    $groups = self::get_group_list($category['id']);
2977
                }
2978
2979
                $content .= '<ul>';
2980
                if (!empty($groups)) {
2981
                    foreach ($groups as $group) {
2982
                        $content .= self::groupOverview($group, $url);
2983
                    }
2984
                }
2985
                $content .= '</ul>';
2986
            }
2987
        }
2988
2989
        // No category
2990
        $groups = self::get_group_list();
2991
        if (!empty($groups)) {
2992
            $content .= '<h2>'.get_lang('NoCategorySelected').'</h2>';
2993
            $content .= '<ul>';
2994
            foreach ($groups as $group) {
2995
                $content = self::groupOverview($group, $url);
2996
            }
2997
            $content .= '</ul>';
2998
        }
2999
3000
        return $content;
3001
    }
3002
3003
    /**
3004
     * Returns the search form.
3005
     *
3006
     * @return string
3007
     */
3008
    public static function getSearchForm()
3009
    {
3010
        $url = api_get_path(WEB_CODE_PATH).'group/group_overview.php?'.api_get_cidreq();
3011
        $form = new FormValidator(
3012
            'search_groups',
3013
            'get',
3014
            $url,
3015
            null,
3016
            ['class' => 'form-search'],
3017
            FormValidator::LAYOUT_INLINE
3018
        );
3019
        $form->addElement('text', 'keyword');
3020
        $form->addButtonSearch();
3021
3022
        return $form->toHtml();
3023
    }
3024
3025
    /**
3026
     * @param int $groupId
3027
     * @param int $status
3028
     */
3029
    public static function setStatus($groupId, $status)
3030
    {
3031
        $groupInfo = self::get_group_properties($groupId);
3032
3033
        $courseId = api_get_course_int_id();
3034
        if (!empty($groupInfo)) {
3035
            $table = Database::get_course_table(TABLE_GROUP);
3036
            $params = [
3037
                'status' => intval($status),
3038
            ];
3039
            Database::update(
3040
                $table,
3041
                $params,
3042
                ['c_id = ? AND id = ?' => [$courseId, $groupId]]
3043
            );
3044
        }
3045
    }
3046
3047
    /**
3048
     * @param int $groupId
3049
     */
3050
    public static function setVisible($groupId)
3051
    {
3052
        self::setStatus($groupId, 1);
3053
    }
3054
3055
    /**
3056
     * @param int $groupId
3057
     */
3058
    public static function setInvisible($groupId)
3059
    {
3060
        self::setStatus($groupId, 0);
3061
    }
3062
3063
    /**
3064
     * @param int   $userId
3065
     * @param int   $courseId
3066
     * @param array $groupInfo
3067
     * @param array $documentInfoToBeCheck
3068
     * @param bool  $blockPage
3069
     *
3070
     * @return bool
3071
     */
3072
    public static function allowUploadEditDocument(
3073
        $userId,
3074
        $courseId,
3075
        $groupInfo,
3076
        $documentInfoToBeCheck = null,
3077
        $blockPage = false
3078
    ) {
3079
        // Admin and teachers can make any change no matter what
3080
        if (api_is_platform_admin() || api_is_allowed_to_edit(false, true)) {
3081
            return true;
3082
        }
3083
3084
        if (empty($groupInfo) || !isset($groupInfo['id'])) {
3085
            if ($blockPage) {
3086
                api_not_allowed(true);
3087
            }
3088
3089
            return false;
3090
        }
3091
3092
        // Tutor can also make any change
3093
        $isTutor = self::is_tutor_of_group($userId, $groupInfo, $courseId);
3094
3095
        if ($isTutor) {
3096
            return true;
3097
        }
3098
3099
        // Just in case also check if document in group is available
3100
        if ($groupInfo['doc_state'] == 0) {
3101
            if ($blockPage) {
3102
                api_not_allowed(true);
3103
            }
3104
3105
            return false;
3106
        }
3107
3108
        // Default behaviour
3109
        $documentAccess = self::DOCUMENT_MODE_SHARE;
3110
3111
        // Check category document access
3112
        /*$allowCategoryGroupDocumentAccess = api_get_configuration_value('group_category_document_access');
3113
        if ($allowCategoryGroupDocumentAccess) {
3114
            $category = GroupManager::get_category_from_group($groupInfo['iid']);
3115
            if (!empty($category) && isset($category['document_access'])) {
3116
                $documentAccess = (int) $category['document_access'];
3117
            }
3118
        }*/
3119
3120
        // Check group document access
3121
        $allow = api_get_configuration_value('group_document_access');
3122
        if ($allow) {
3123
            if (isset($groupInfo['document_access'])) {
3124
                $documentAccess = (int) $groupInfo['document_access'];
3125
            }
3126
        }
3127
3128
        // Check access for students
3129
        $result = false;
3130
        switch ($documentAccess) {
3131
            case self::DOCUMENT_MODE_SHARE:
3132
                // Default chamilo behaviour
3133
                // Student can upload his own content, cannot modify another content.
3134
                $isMember = self::is_subscribed($userId, $groupInfo);
3135
                if ($isMember) {
3136
                    // No document to check, allow access to document feature.
3137
                    if (empty($documentInfoToBeCheck)) {
3138
                        $result = true;
3139
                    } else {
3140
                        // Member can only edit his own document
3141
                        $authorId = isset($documentInfoToBeCheck['insert_user_id']) ? $documentInfoToBeCheck['insert_user_id'] : 0;
3142
                        // If "insert_user_id" is not set, check the author id from c_item_property
3143
                        if (empty($authorId) && isset($documentInfoToBeCheck['id'])) {
3144
                            $documentInfo = api_get_item_property_info(
3145
                                $courseId,
3146
                                'document',
3147
                                $documentInfoToBeCheck['id'],
3148
                                0
3149
                            );
3150
                            // Try to find this document in the session
3151
                            if (!empty($sessionId)) {
3152
                                $documentInfo = api_get_item_property_info(
3153
                                    $courseId,
3154
                                    'document',
3155
                                    $documentInfoToBeCheck['id'],
3156
                                    api_get_session_id()
3157
                                );
3158
                            }
3159
3160
                            if (!empty($documentInfo) && isset($documentInfo['insert_user_id'])) {
3161
                                $authorId = $documentInfo['insert_user_id'];
3162
                            }
3163
                        }
3164
3165
                        if ($authorId == $userId) {
3166
                            $result = true;
3167
                        }
3168
                    }
3169
                }
3170
                break;
3171
            case self::DOCUMENT_MODE_READ_ONLY:
3172
                // Student cannot upload content, cannot modify another content.
3173
                $result = false;
3174
                break;
3175
            case self::DOCUMENT_MODE_COLLABORATION:
3176
                // Student can upload content, can modify another content.
3177
                $isMember = self::is_subscribed($userId, $groupInfo);
3178
                if ($isMember) {
3179
                    $result = true;
3180
                }
3181
                break;
3182
        }
3183
3184
        if ($blockPage && $result == false) {
3185
            api_not_allowed(true);
3186
        }
3187
3188
        return $result;
3189
    }
3190
}
3191