Passed
Push — 1.11.x ( d5692e...7dcd30 )
by Julito
12:49
created

GroupManager::set_group_properties()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 63
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 38
nc 8
nop 15
dl 0
loc 63
rs 9.0008
c 0
b 0
f 0

How to fix   Long Method    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
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CourseBundle\Entity\CGroupRelUser;
6
7
/**
8
 * This library contains some functions for group-management.
9
 *
10
 * @author Bart Mollet
11
 *
12
 * @todo Add $course_code parameter to all functions. So this GroupManager can
13
 * be used outside a session.
14
 */
15
class GroupManager
16
{
17
    /* DEFAULT_GROUP_CATEGORY:
18
    When group categories aren't available (platform-setting),
19
    all groups are created in this 'dummy'-category*/
20
    const DEFAULT_GROUP_CATEGORY = 2;
21
22
    /**
23
     * infinite.
24
     */
25
    const INFINITE = 99999;
26
    /**
27
     * No limit on the number of users in a group.
28
     */
29
    const MEMBER_PER_GROUP_NO_LIMIT = 0;
30
    /**
31
     * No limit on the number of groups per user.
32
     */
33
    const GROUP_PER_MEMBER_NO_LIMIT = 0;
34
    /**
35
     * The tools of a group can have 3 states
36
     * - not available
37
     * - public
38
     * - private.
39
     */
40
    const TOOL_NOT_AVAILABLE = 0;
41
    const TOOL_PUBLIC = 1;
42
    const TOOL_PRIVATE = 2;
43
    const TOOL_PRIVATE_BETWEEN_USERS = 3;
44
45
    /**
46
     * Constants for the available group tools.
47
     */
48
    const GROUP_TOOL_FORUM = 0;
49
    const GROUP_TOOL_DOCUMENTS = 1;
50
    const GROUP_TOOL_CALENDAR = 2;
51
    const GROUP_TOOL_ANNOUNCEMENT = 3;
52
    const GROUP_TOOL_WORK = 4;
53
    const GROUP_TOOL_WIKI = 5;
54
    const GROUP_TOOL_CHAT = 6;
55
56
    const DOCUMENT_MODE_SHARE = 0; // By default
57
    const DOCUMENT_MODE_READ_ONLY = 1;
58
    const DOCUMENT_MODE_COLLABORATION = 2;
59
60
    /**
61
     * GroupManager constructor.
62
     */
63
    public function __construct()
64
    {
65
    }
66
67
    /**
68
     * @param int $courseId
69
     *
70
     * @return array
71
     */
72
    public static function get_groups($courseId = 0)
73
    {
74
        $table_group = Database::get_course_table(TABLE_GROUP);
75
        $courseId = !empty($courseId) ? (int) $courseId : api_get_course_int_id();
76
77
        $sql = "SELECT * FROM $table_group WHERE c_id = $courseId  ";
78
        $result = Database::query($sql);
79
80
        return Database::store_result($result, 'ASSOC');
81
    }
82
83
    /**
84
     * Get list of groups for current course.
85
     *
86
     * @param int   $categoryId  The id of the category from which the groups are
87
     *                           requested
88
     * @param array $course_info Default is current course
89
     * @param int   $status      group status
90
     * @param int   $sessionId
91
     * @param bool  $getCount
92
     * @param bool  $notInGroup  Get groups not in a category
93
     *
94
     * @return array an array with all information about the groups
95
     */
96
    public static function get_group_list(
97
        $categoryId = null,
98
        $course_info = [],
99
        $status = null,
100
        $sessionId = 0,
101
        $getCount = false,
102
        $notInGroup = false
103
    ) {
104
        $course_info = empty($course_info) ? api_get_course_info() : $course_info;
105
        if (empty($course_info)) {
106
            return [];
107
        }
108
        $sessionId = empty($sessionId) ? api_get_session_id() : (int) $sessionId;
109
        $course_id = $course_info['real_id'];
110
        $table_group = Database::get_course_table(TABLE_GROUP);
111
112
        $select = ' g.id,
113
                    g.iid,
114
                    g.name,
115
                    g.description,
116
                    g.category_id,
117
                    g.max_student maximum_number_of_members,
118
                    g.secret_directory,
119
                    g.self_registration_allowed,
120
                    g.self_unregistration_allowed,
121
                    g.session_id,
122
                    g.status';
123
        if ($getCount) {
124
            $select = ' DISTINCT count(g.iid) as count ';
125
        }
126
127
        $sql = "SELECT
128
                $select
129
                FROM $table_group g
130
                WHERE 1 = 1 ";
131
132
        if (!is_null($categoryId)) {
133
            $sql .= " AND g.category_id = '".intval($categoryId)."' ";
134
            $session_condition = api_get_session_condition($sessionId);
135
            if (!empty($session_condition)) {
136
                $sql .= $session_condition;
137
            }
138
        } else {
139
            $session_condition = api_get_session_condition($sessionId, true);
140
        }
141
142
        if (!is_null($status)) {
143
            $sql .= " AND g.status = '".intval($status)."' ";
144
        }
145
146
        $sql .= " AND g.c_id = $course_id ";
147
148
        if ($notInGroup) {
149
            $sql .= "  AND (g.category_id IS NULL OR g.category_id = 0) ";
150
        }
151
152
        if (!empty($session_condition)) {
153
            $sql .= $session_condition;
154
        }
155
        $sql .= ' ORDER BY UPPER(g.name)';
156
157
        $result = Database::query($sql);
158
159
        if ($getCount) {
160
            $row = Database::fetch_array($result);
161
162
            return $row['count'];
163
        }
164
165
        $groups = [];
166
        while ($thisGroup = Database::fetch_array($result)) {
167
            $thisGroup['number_of_members'] = count(self::get_subscribed_users($thisGroup));
168
            if ($thisGroup['session_id'] != 0) {
169
                $sql = 'SELECT name FROM '.Database::get_main_table(TABLE_MAIN_SESSION).'
170
                        WHERE id='.$thisGroup['session_id'];
171
                $rs_session = Database::query($sql);
172
                if (Database::num_rows($rs_session) > 0) {
173
                    $thisGroup['session_name'] = Database::result($rs_session, 0, 0);
174
                }
175
            }
176
            $groups[] = $thisGroup;
177
        }
178
179
        return $groups;
180
    }
181
182
    /**
183
     * Create a group.
184
     *
185
     * @param string $name        The name for this group
186
     * @param int    $category_id
187
     * @param int    $tutor       The user-id of the group's tutor
188
     * @param int    $places      How many people can subscribe to the new group
189
     *
190
     * @return int
191
     */
192
    public static function create_group($name, $category_id, $tutor, $places)
193
    {
194
        $_course = api_get_course_info();
195
        $session_id = api_get_session_id();
196
        $course_id = $_course['real_id'];
197
        $currentCourseRepository = $_course['path'];
198
        $category = self::get_category($category_id);
199
        $places = (int) $places;
200
201
        // Default values
202
        $docState = self::TOOL_PRIVATE;
203
        $calendarState = self::TOOL_PRIVATE;
204
        $workState = self::TOOL_PRIVATE;
205
        $anonuncementState = self::TOOL_PRIVATE;
206
        $forumState = self::TOOL_PRIVATE;
207
        $wikiState = self::TOOL_PRIVATE;
208
        $chatState = self::TOOL_PRIVATE;
209
        $selfRegAllowed = 0;
210
        $selfUnregAllwoed = 0;
211
        $documentAccess = 0;
212
213
        if ($category) {
214
            if ($places == 0) {
215
                //if the amount of users per group is not filled in, use the setting from the category
216
                $places = $category['max_student'];
217
            } else {
218
                if ($places > $category['max_student'] && $category['max_student'] != 0) {
219
                    $places = $category['max_student'];
220
                }
221
            }
222
            $docState = $category['doc_state'];
223
            $calendarState = $category['calendar_state'];
224
            $workState = $category['work_state'];
225
            $anonuncementState = $category['announcements_state'];
226
            $forumState = $category['forum_state'];
227
            $wikiState = $category['wiki_state'];
228
            $chatState = $category['chat_state'];
229
            $selfRegAllowed = $category['self_reg_allowed'];
230
            $selfUnregAllwoed = $category['self_unreg_allowed'];
231
            $documentAccess = isset($category['document_access']) ? $category['document_access'] : 0;
232
        }
233
234
        $allowDocumentAccess = api_get_configuration_value('group_document_access');
235
        $documentCondition = '';
236
        if ($allowDocumentAccess) {
237
            $documentAccess = (int) $documentAccess;
238
            $documentCondition = " document_access = $documentAccess, ";
239
        }
240
241
        $table_group = Database::get_course_table(TABLE_GROUP);
242
        $sql = "INSERT INTO $table_group SET
243
                c_id = $course_id,
244
                status = 1,
245
                category_id='".Database::escape_string($category_id)."',
246
                max_student = '".$places."',
247
                doc_state = '".$docState."',
248
                calendar_state = '".$calendarState."',
249
                work_state = '".$workState."',
250
                announcements_state = '".$anonuncementState."',
251
                forum_state = '".$forumState."',
252
                wiki_state = '".$wikiState."',
253
                chat_state = '".$chatState."',
254
                self_registration_allowed = '".$selfRegAllowed."',
255
                self_unregistration_allowed = '".$selfUnregAllwoed."',
256
                $documentCondition
257
                session_id='".$session_id."'";
258
259
        Database::query($sql);
260
        $lastId = Database::insert_id();
261
262
        if ($lastId) {
263
            $sql = "UPDATE $table_group SET id = iid WHERE iid = $lastId";
264
            Database::query($sql);
265
266
            $desired_dir_name = '/'.api_replace_dangerous_char($name).'_groupdocs';
267
            $my_path = api_get_path(SYS_COURSE_PATH).$currentCourseRepository.'/document';
268
269
            $newFolderData = create_unexisting_directory(
270
                $_course,
271
                api_get_user_id(),
272
                $session_id,
273
                $lastId,
274
                null,
275
                $my_path,
276
                $desired_dir_name,
277
                null,
278
                1
279
            );
280
281
            $unique_name = $newFolderData['path'];
282
283
            /* Stores the directory path into the group table */
284
            $sql = "UPDATE $table_group SET
285
                        name = '".Database::escape_string($name)."',
286
                        secret_directory = '".$unique_name."'
287
                    WHERE c_id = $course_id AND id ='".$lastId."'";
288
289
            Database::query($sql);
290
291
            // create a forum if needed
292
            if ($forumState >= 0) {
293
                require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
294
295
                $forum_categories = get_forum_categories();
296
                if (empty($forum_categories)) {
297
                    $categoryParam = [
298
                        'forum_category_title' => get_lang('GroupForums'),
299
                    ];
300
                    store_forumcategory($categoryParam);
301
                    $forum_categories = get_forum_categories();
302
                }
303
304
                $counter = 0;
305
                foreach ($forum_categories as $key => $value) {
306
                    if ($counter == 0) {
307
                        $forum_category_id = $key;
308
                    }
309
                    $counter++;
310
                }
311
                // A sanity check.
312
                if (empty($forum_category_id)) {
313
                    $forum_category_id = 0;
314
                }
315
316
                $values = [];
317
                $values['forum_title'] = $name;
318
                $values['group_id'] = $lastId;
319
                $values['forum_category'] = $forum_category_id;
320
                $values['allow_anonymous_group']['allow_anonymous'] = 0;
321
                $values['students_can_edit_group']['students_can_edit'] = 0;
322
                $values['approval_direct_group']['approval_direct'] = 0;
323
                $values['allow_attachments_group']['allow_attachments'] = 1;
324
                $values['allow_new_threads_group']['allow_new_threads'] = 1;
325
                $values['default_view_type_group']['default_view_type'] = api_get_setting('default_forum_view');
326
                $values['group_forum'] = $lastId;
327
                if ($forumState == '1') {
328
                    $values['public_private_group_forum_group']['public_private_group_forum'] = 'public';
329
                } elseif ($forumState == '2') {
330
                    $values['public_private_group_forum_group']['public_private_group_forum'] = 'private';
331
                } elseif ($forumState == '0') {
332
                    $values['public_private_group_forum_group']['public_private_group_forum'] = 'unavailable';
333
                }
334
                store_forum($values);
335
            }
336
        }
337
338
        return $lastId;
339
    }
340
341
    /**
342
     * Create subgroups.
343
     * This function creates new groups based on an existing group. It will
344
     * create the specified number of groups and fill those groups with users
345
     * from the base group.
346
     *
347
     * @param int $group_id         the group from which subgroups have to be created
348
     * @param int $number_of_groups The number of groups that have to be created
349
     */
350
    public static function create_subgroups($group_id, $number_of_groups)
351
    {
352
        $courseId = api_get_course_int_id();
353
        $table_group = Database::get_course_table(TABLE_GROUP);
354
        $category_id = self::create_category(
355
            get_lang('Subgroups'),
356
            '',
357
            self::TOOL_PRIVATE,
358
            self::TOOL_PRIVATE,
359
            0,
360
            0,
361
            1,
362
            1
363
        );
364
        $users = self::get_users($group_id);
365
        $group_ids = [];
366
367
        for ($group_nr = 1; $group_nr <= $number_of_groups; $group_nr++) {
368
            $group_ids[] = self::create_group(
369
                get_lang('Subgroup').' '.$group_nr,
370
                $category_id,
371
                0,
372
                0
373
            );
374
        }
375
376
        $members = [];
377
        foreach ($users as $index => $user_id) {
378
            $groupId = $group_ids[$index % $number_of_groups];
379
            $groupInfo = self::get_group_properties($groupId);
380
            self::subscribe_users(
381
                $user_id,
382
                $groupInfo
383
            );
384
            $members[$group_ids[$groupId]]++;
385
        }
386
387
        foreach ($members as $group_id => $places) {
388
            $sql = "UPDATE $table_group SET max_student = $places
389
                    WHERE c_id = $courseId  AND id = $group_id";
390
            Database::query($sql);
391
        }
392
    }
393
394
    /**
395
     * Create a group for every class subscribed to the current course.
396
     *
397
     * @param int $categoryId The category in which the groups should be created
398
     *
399
     * @return array
400
     */
401
    public static function create_class_groups($categoryId)
402
    {
403
        $options = [];
404
        $sessionId = api_get_session_id();
405
        if (empty($sessionId)) {
406
            $options['where'] = [' usergroup.course_id = ? ' => api_get_course_int_id()];
407
        } else {
408
            $options['session_id'] = $sessionId;
409
            $options['where'] = [' usergroup.session_id = ? ' => $sessionId];
410
        }
411
412
        $obj = new UserGroup();
413
        $classes = $obj->getUserGroupInCourse($options);
414
        $group_ids = [];
415
416
        foreach ($classes as $class) {
417
            $userList = $obj->get_users_by_usergroup($class['id']);
418
            $groupId = self::create_group(
419
                $class['name'],
420
                $categoryId,
421
                0,
422
                null
423
            );
424
425
            if ($groupId) {
426
                $groupInfo = self::get_group_properties($groupId);
427
                self::subscribe_users($userList, $groupInfo);
428
                $group_ids[] = $groupId;
429
            }
430
        }
431
432
        return $group_ids;
433
    }
434
435
    /**
436
     * Deletes groups and their data.
437
     *
438
     * @author Christophe Gesche <[email protected]>
439
     * @author Hugues Peeters <[email protected]>
440
     * @author Bart Mollet
441
     *
442
     * @param array  $groupInfo   iid
443
     * @param string $course_code Default is current course
444
     *
445
     * @return int - number of groups deleted
446
     */
447
    public static function deleteGroup($groupInfo, $course_code = null)
448
    {
449
        if (empty($groupInfo['iid'])) {
450
            return false;
451
        }
452
        $course_info = api_get_course_info($course_code);
453
        if (empty($course_info)) {
454
            return false;
455
        }
456
457
        $course_id = $course_info['real_id'];
458
459
        // Database table definitions
460
        $group_table = Database::get_course_table(TABLE_GROUP);
461
        $forum_table = Database::get_course_table(TABLE_FORUM);
462
        $groupInfo = self::get_group_properties($groupInfo['iid'], true);
463
        if ($groupInfo) {
464
            $groupIid = $groupInfo['iid'];
465
            $groupId = $groupInfo['id'];
466
            // Unsubscribe all users
467
            self::unsubscribe_all_users($groupInfo);
468
            self::unsubscribe_all_tutors($groupInfo);
469
470
            if (!empty($groupInfo['secret_directory'])) {
471
                $directory = $groupInfo['secret_directory'];
472
                // move group-documents to garbage
473
                $source_directory = api_get_path(SYS_COURSE_PATH).$course_info['path']."/document".$directory;
474
                // File to renamed
475
                $destination_dir = api_get_path(SYS_COURSE_PATH).$course_info['path']."/document".$directory.'_DELETED_'.$groupInfo['id'];
476
                //Deleting from document tool
477
                DocumentManager::delete_document(
478
                    $course_info,
479
                    $directory,
480
                    $source_directory
481
                );
482
483
                if (file_exists($source_directory)) {
484
                    if (api_get_setting('permanently_remove_deleted_files') === 'true') {
485
                        // Delete
486
                        my_delete($source_directory);
487
                    } else {
488
                        // Rename
489
                        rename($source_directory, $destination_dir);
490
                    }
491
                }
492
            }
493
494
            $sql = "DELETE FROM $forum_table
495
                    WHERE c_id = $course_id AND forum_of_group = $groupId ";
496
            Database::query($sql);
497
498
            // Delete item properties of this group.
499
            // to_group_id is related to c_group_info.iid
500
            $itemPropertyTable = Database::get_course_table(TABLE_ITEM_PROPERTY);
501
            $sql = "DELETE FROM $itemPropertyTable
502
                    WHERE c_id = $course_id AND to_group_id = $groupIid ";
503
            Database::query($sql);
504
505
            // delete the groups
506
            $sql = "DELETE FROM $group_table
507
                    WHERE c_id = $course_id AND iid = $groupIid ";
508
            Database::query($sql);
509
        }
510
511
        return true;
512
    }
513
514
    /**
515
     * Function needed only when deleting a course, in order to be sure that all group ids are deleted.
516
     *
517
     * @param int $courseId
518
     *
519
     * @return bool
520
     */
521
    public static function deleteAllGroupsFromCourse($courseId)
522
    {
523
        $courseId = (int) $courseId;
524
525
        if (empty($courseId)) {
526
            return false;
527
        }
528
529
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
530
        $sql = "SELECT iid FROM $table
531
                WHERE c_id = $courseId ";
532
        Database::query($sql);
533
534
        // Database table definitions
535
        $table = Database::get_course_table(TABLE_GROUP_USER);
536
        $sql = "DELETE FROM $table
537
                WHERE c_id = $courseId";
538
        Database::query($sql);
539
540
        $table = Database::get_course_table(TABLE_GROUP_TUTOR);
541
        $sql = "DELETE FROM $table
542
                WHERE c_id = $courseId";
543
        Database::query($sql);
544
545
        $groupTable = Database::get_course_table(TABLE_GROUP);
546
        $sql = "DELETE FROM $groupTable
547
                WHERE c_id = $courseId";
548
        Database::query($sql);
549
550
        return true;
551
    }
552
553
    /**
554
     * Get group properties.
555
     *
556
     * @param int  $group_id the group from which properties are requested
557
     * @param bool $useIid
558
     *
559
     * @return array All properties. Array-keys are:
560
     *               name, tutor_id, description, maximum_number_of_students,
561
     *               directory and visibility of tools
562
     */
563
    public static function get_group_properties($group_id, $useIid = false)
564
    {
565
        $course_id = api_get_course_int_id();
566
        $group_id = (int) $group_id;
567
568
        if (empty($group_id)) {
569
            return null;
570
        }
571
572
        $table_group = Database::get_course_table(TABLE_GROUP);
573
        $sql = "SELECT * FROM $table_group
574
                WHERE c_id = $course_id AND id = ".$group_id;
575
576
        if ($useIid) {
577
            $sql = "SELECT * FROM $table_group
578
                    WHERE c_id = $course_id AND iid = ".$group_id;
579
        }
580
        $db_result = Database::query($sql);
581
        $db_object = Database::fetch_object($db_result);
582
583
        $result = [];
584
        if ($db_object) {
585
            $result['id'] = $db_object->id;
586
            $result['iid'] = $db_object->iid;
587
            $result['name'] = $db_object->name;
588
            $result['status'] = $db_object->status;
589
            $result['description'] = $db_object->description;
590
            $result['maximum_number_of_students'] = $db_object->max_student;
591
            $result['max_student'] = $db_object->max_student;
592
            $result['doc_state'] = $db_object->doc_state;
593
            $result['work_state'] = $db_object->work_state;
594
            $result['calendar_state'] = $db_object->calendar_state;
595
            $result['announcements_state'] = $db_object->announcements_state;
596
            $result['forum_state'] = $db_object->forum_state;
597
            $result['wiki_state'] = $db_object->wiki_state;
598
            $result['chat_state'] = $db_object->chat_state;
599
            $result['directory'] = $db_object->secret_directory;
600
            $result['self_registration_allowed'] = $db_object->self_registration_allowed;
601
            $result['self_unregistration_allowed'] = $db_object->self_unregistration_allowed;
602
            $result['count_users'] = count(
603
                self::get_subscribed_users($result)
604
            );
605
            $result['count_tutor'] = count(
606
                self::get_subscribed_tutors($result)
607
            );
608
            $result['count_all'] = $result['count_users'] + $result['count_tutor'];
609
            $result['document_access'] = isset($db_object->document_access) ? $db_object->document_access : self::DOCUMENT_MODE_SHARE;
610
        }
611
612
        return $result;
613
    }
614
615
    /**
616
     * @param string $name
617
     * @param string $courseCode
618
     * @param int    $sessionId
619
     *
620
     * @return array
621
     */
622
    public static function getGroupByName($name, $courseCode = null, $sessionId = 0)
623
    {
624
        $name = trim($name);
625
626
        if (empty($name)) {
627
            return [];
628
        }
629
630
        $course_info = api_get_course_info($courseCode);
631
        $course_id = $course_info['real_id'];
632
        $name = Database::escape_string($name);
633
        $sessionId = empty($sessionId) ? api_get_session_id() : (int) $sessionId;
634
        $sessionCondition = api_get_session_condition($sessionId);
635
636
        $table = Database::get_course_table(TABLE_GROUP);
637
        $sql = "SELECT * FROM $table
638
                WHERE
639
                  c_id = $course_id AND
640
                  name = '$name'
641
                  $sessionCondition
642
                LIMIT 1";
643
        $res = Database::query($sql);
644
        $group = [];
645
        if (Database::num_rows($res)) {
646
            $group = Database::fetch_array($res, 'ASSOC');
647
        }
648
649
        return $group;
650
    }
651
652
    /**
653
     * @param int    $courseId
654
     * @param int    $categoryId
655
     * @param string $name
656
     *
657
     * @return array
658
     */
659
    public static function getGroupListFilterByName($name, $categoryId, $courseId)
660
    {
661
        $name = Database::escape_string(trim($name));
662
        $categoryId = (int) $categoryId;
663
        $courseId = (int) $courseId;
664
665
        if (empty($name)) {
666
            return [];
667
        }
668
        $table = Database::get_course_table(TABLE_GROUP);
669
        $sql = "SELECT * FROM $table
670
                WHERE c_id = $courseId AND name LIKE '%$name%'";
671
672
        if (!empty($categoryId)) {
673
            $sql .= " AND category_id = $categoryId";
674
        }
675
        $sql .= " ORDER BY name";
676
        $result = Database::query($sql);
677
678
        return Database::store_result($result, 'ASSOC');
679
    }
680
681
    /**
682
     * Set group properties
683
     * Changes the group's properties.
684
     *
685
     * @param int       Group Id
686
     * @param string    Group name
687
     * @param string    Group description
688
     * @param int       Max number of students in group
689
     * @param int       Document tool's visibility (0=none,1=private,2=public)
690
     * @param int       Work tool's visibility (0=none,1=private,2=public)
691
     * @param int       Calendar tool's visibility (0=none,1=private,2=public)
692
     * @param int       Announcement tool's visibility (0=none,1=private,2=public)
693
     * @param int       Forum tool's visibility (0=none,1=private,2=public)
694
     * @param int       Wiki tool's visibility (0=none,1=private,2=public)
695
     * @param int       Chat tool's visibility (0=none,1=private,2=public)
696
     * @param bool Whether self registration is allowed or not
697
     * @param bool Whether self unregistration is allowed or not
698
     * @param int $categoryId
699
     * @param int $documentAccess
700
     *
701
     * @return bool TRUE if properties are successfully changed, false otherwise
702
     */
703
    public static function set_group_properties(
704
        $group_id,
705
        $name,
706
        $description,
707
        $maximum_number_of_students,
708
        $doc_state,
709
        $work_state,
710
        $calendar_state,
711
        $announcements_state,
712
        $forum_state,
713
        $wiki_state,
714
        $chat_state,
715
        $selfRegistrationAllowed,
716
        $selfUnRegistrationAllowed,
717
        $categoryId = null,
718
        $documentAccess = 0
719
    ) {
720
        $table_group = Database::get_course_table(TABLE_GROUP);
721
        $table_forum = Database::get_course_table(TABLE_FORUM);
722
        $categoryId = (int) $categoryId;
723
        $group_id = (int) $group_id;
724
        $courseId = api_get_course_int_id();
725
726
        $allowDocumentAccess = api_get_configuration_value('group_document_access');
727
        $documentCondition = '';
728
        if ($allowDocumentAccess) {
729
            $documentAccess = (int) $documentAccess;
730
            $documentCondition = " document_access = $documentAccess, ";
731
        }
732
733
        $sql = "UPDATE ".$table_group." SET
734
                    name='".Database::escape_string(trim($name))."',
735
                    doc_state = '".Database::escape_string($doc_state)."',
736
                    work_state = '".Database::escape_string($work_state)."',
737
                    calendar_state = '".Database::escape_string($calendar_state)."',
738
                    announcements_state = '".Database::escape_string($announcements_state)."',
739
                    forum_state = '".Database::escape_string($forum_state)."',
740
                    wiki_state = '".Database::escape_string($wiki_state)."',
741
                    chat_state = '".Database::escape_string($chat_state)."',
742
                    description ='".Database::escape_string(trim($description))."',
743
                    max_student = '".Database::escape_string($maximum_number_of_students)."',
744
                    self_registration_allowed = '".Database::escape_string($selfRegistrationAllowed)."',
745
                    self_unregistration_allowed = '".Database::escape_string($selfUnRegistrationAllowed)."',
746
                    $documentCondition
747
                    category_id = ".$categoryId."
748
                WHERE c_id = $courseId AND id=".$group_id;
749
        $result = Database::query($sql);
750
751
        /* Here we are updating a field in the table forum_forum that perhaps
752
        duplicates the table group_info.forum_state cvargas*/
753
        $forum_state = (int) $forum_state;
754
        $sql2 = "UPDATE ".$table_forum." SET ";
755
        if (1 === $forum_state) {
756
            $sql2 .= " forum_group_public_private='public' ";
757
        } elseif (2 === $forum_state) {
758
            $sql2 .= " forum_group_public_private='private' ";
759
        } elseif (0 === $forum_state) {
760
            $sql2 .= " forum_group_public_private='unavailable' ";
761
        }
762
        $sql2 .= " WHERE c_id = $courseId AND forum_of_group=".$group_id;
763
        Database::query($sql2);
764
765
        return $result;
766
    }
767
768
    /**
769
     * Get the total number of groups for the current course.
770
     *
771
     * @return int the number of groups for the current course
772
     */
773
    public static function get_number_of_groups()
774
    {
775
        $courseId = api_get_course_int_id();
776
        $table = Database::get_course_table(TABLE_GROUP);
777
        $sql = "SELECT COUNT(id) AS number_of_groups
778
                FROM $table
779
                WHERE c_id = $courseId ";
780
        $res = Database::query($sql);
781
        $obj = Database::fetch_object($res);
782
783
        return $obj->number_of_groups;
784
    }
785
786
    /**
787
     * Get all categories.
788
     *
789
     * @param string $course_code The course (default = current course)
790
     *
791
     * @return array
792
     */
793
    public static function get_categories($course_code = null)
794
    {
795
        $course_info = api_get_course_info($course_code);
796
        $courseId = $course_info['real_id'];
797
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
798
        $sql = "SELECT * FROM $table
799
                WHERE c_id = $courseId
800
                ORDER BY display_order";
801
        $res = Database::query($sql);
802
        $cats = [];
803
        while ($cat = Database::fetch_array($res)) {
804
            $cats[] = $cat;
805
        }
806
807
        return $cats;
808
    }
809
810
    /**
811
     * Get a group category.
812
     *
813
     * @param int    $id          The category id
814
     * @param string $course_code The course (default = current course)
815
     *
816
     * @return array
817
     */
818
    public static function get_category($id, $course_code = null)
819
    {
820
        if (empty($id)) {
821
            return [];
822
        }
823
824
        $courseInfo = api_get_course_info($course_code);
825
        $courseId = $courseInfo['real_id'];
826
        $id = intval($id);
827
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
828
        $sql = "SELECT * FROM $table
829
                WHERE c_id = $courseId AND id = $id
830
                LIMIT 1";
831
        $res = Database::query($sql);
832
833
        return Database::fetch_array($res);
834
    }
835
836
    /**
837
     * Get a group category.
838
     *
839
     * @param string $title
840
     * @param string $course_code The course (default = current course)
841
     *
842
     * @return array
843
     */
844
    public static function getCategoryByTitle($title, $course_code = null)
845
    {
846
        $title = trim($title);
847
848
        if (empty($title)) {
849
            return [];
850
        }
851
852
        $course_info = api_get_course_info($course_code);
853
        $courseId = $course_info['real_id'];
854
        $title = Database::escape_string($title);
855
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
856
        $sql = "SELECT * FROM $table
857
                WHERE c_id = $courseId AND title = '$title'
858
                LIMIT 1";
859
        $res = Database::query($sql);
860
        $category = [];
861
        if (Database::num_rows($res)) {
862
            $category = Database::fetch_array($res, 'ASSOC');
863
        }
864
865
        return $category;
866
    }
867
868
    /**
869
     * Get the unique category of a given group.
870
     *
871
     * @param int    $group_id    The iid of the group
872
     * @param string $course_code The course in which the group is (default =
873
     *                            current course)
874
     *
875
     * @return array The category
876
     */
877
    public static function get_category_from_group($group_id, $course_code = '')
878
    {
879
        $table_group = Database::get_course_table(TABLE_GROUP);
880
        $table_group_cat = Database::get_course_table(TABLE_GROUP_CATEGORY);
881
882
        $group_id = (int) $group_id;
883
884
        if (empty($group_id)) {
885
            return [];
886
        }
887
888
        $course_info = api_get_course_info($course_code);
889
890
        if (empty($course_info)) {
891
            return false;
892
        }
893
894
        $courseId = $course_info['real_id'];
895
        $sql = "SELECT gc.* FROM $table_group_cat gc, $table_group g
896
                WHERE
897
                    gc.c_id = $courseId AND
898
                    g.c_id = $courseId AND
899
                    gc.id = g.category_id AND
900
                    g.iid = $group_id
901
                LIMIT 1";
902
        $res = Database::query($sql);
903
        $cat = [];
904
        if (Database::num_rows($res)) {
905
            $cat = Database::fetch_array($res);
906
        }
907
908
        return $cat;
909
    }
910
911
    /**
912
     * Delete a group category.
913
     *
914
     * @param int    $cat_id      The id of the category to delete
915
     * @param string $course_code The code in which the category should be
916
     *                            deleted (default = current course)
917
     *
918
     * @return bool
919
     */
920
    public static function delete_category($cat_id, $course_code = '')
921
    {
922
        $course_info = api_get_course_info($course_code);
923
        if (empty($course_info)) {
924
            return false;
925
        }
926
        $course_id = $course_info['real_id'];
927
928
        $table_group = Database::get_course_table(TABLE_GROUP);
929
        $table_group_cat = Database::get_course_table(TABLE_GROUP_CATEGORY);
930
        $cat_id = intval($cat_id);
931
        $sql = "SELECT iid FROM $table_group
932
                WHERE c_id = $course_id AND category_id='".$cat_id."'";
933
        $res = Database::query($sql);
934
        if (Database::num_rows($res) > 0) {
935
            while ($group = Database::fetch_object($res)) {
936
                // Delete all groups in category
937
                /*$groupInfo = self::get_group_properties($group->iid, true);
938
                self::deleteGroup($groupInfo, $course_code);
939
                */
940
                // Set the category to NULL to avoid losing groups in sessions.
941
                $sql = "UPDATE $table_group SET category_id = NULL WHERE iid = ".$group->iid;
942
                Database::query($sql);
943
            }
944
        }
945
        $sql = "DELETE FROM $table_group_cat
946
                WHERE c_id = $course_id  AND id='".$cat_id."'";
947
        Database::query($sql);
948
949
        return true;
950
    }
951
952
    /**
953
     * Create group category.
954
     *
955
     * @param string $title                      The title of the new category
956
     * @param string $description                The description of the new category
957
     * @param int    $doc_state
958
     * @param int    $work_state
959
     * @param int    $calendar_state
960
     * @param int    $announcements_state
961
     * @param int    $forum_state
962
     * @param int    $wiki_state
963
     * @param int    $chat_state
964
     * @param int    $selfRegistrationAllowed    allow users to self register
965
     * @param int    $selfUnRegistrationAllowed  allow user to self unregister
966
     * @param int    $maximum_number_of_students
967
     * @param int    $groups_per_user
968
     * @param int    $documentAccess             document access
969
     *
970
     * @return mixed
971
     */
972
    public static function create_category(
973
        $title,
974
        $description,
975
        $doc_state,
976
        $work_state,
977
        $calendar_state,
978
        $announcements_state,
979
        $forum_state,
980
        $wiki_state,
981
        $chat_state = 1,
982
        $selfRegistrationAllowed = 0,
983
        $selfUnRegistrationAllowed = 0,
984
        $maximum_number_of_students = 8,
985
        $groups_per_user = 0,
986
        $documentAccess = 0
987
    ) {
988
        if (empty($title)) {
989
            return false;
990
        }
991
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
992
        $course_id = api_get_course_int_id();
993
994
        $sql = "SELECT MAX(display_order)+1 as new_order
995
                FROM $table
996
                WHERE c_id = $course_id ";
997
        $res = Database::query($sql);
998
        $obj = Database::fetch_object($res);
999
        if (!isset($obj->new_order)) {
1000
            $obj->new_order = 1;
1001
        }
1002
1003
        $params = [
1004
            'c_id' => $course_id,
1005
            'title' => $title,
1006
            'display_order' => $obj->new_order,
1007
            'description' => $description,
1008
            'doc_state' => $doc_state,
1009
            'work_state' => $work_state,
1010
            'calendar_state' => $calendar_state,
1011
            'announcements_state' => $announcements_state,
1012
            'forum_state' => $forum_state,
1013
            'wiki_state' => $wiki_state,
1014
            'chat_state' => $chat_state,
1015
            'groups_per_user' => $groups_per_user,
1016
            'self_reg_allowed' => $selfRegistrationAllowed,
1017
            'self_unreg_allowed' => $selfUnRegistrationAllowed,
1018
            'max_student' => $maximum_number_of_students,
1019
        ];
1020
1021
        $allowDocumentAccess = api_get_configuration_value('group_category_document_access');
1022
        if ($allowDocumentAccess) {
1023
            $params['document_access'] = $documentAccess;
1024
        }
1025
1026
        $categoryId = Database::insert($table, $params);
1027
        if ($categoryId) {
1028
            $sql = "UPDATE $table SET id = iid
1029
                    WHERE iid = $categoryId";
1030
            Database::query($sql);
1031
1032
            return $categoryId;
1033
        }
1034
1035
        return false;
1036
    }
1037
1038
    /**
1039
     * Update group category.
1040
     *
1041
     * @param int    $id
1042
     * @param string $title
1043
     * @param string $description
1044
     * @param $doc_state
1045
     * @param $work_state
1046
     * @param $calendar_state
1047
     * @param $announcements_state
1048
     * @param $forum_state
1049
     * @param $wiki_state
1050
     * @param $chat_state
1051
     * @param $selfRegistrationAllowed
1052
     * @param $selfUnRegistrationAllowed
1053
     * @param $maximum_number_of_students
1054
     * @param $groups_per_user
1055
     * @param $documentAccess
1056
     */
1057
    public static function update_category(
1058
        $id,
1059
        $title,
1060
        $description,
1061
        $doc_state,
1062
        $work_state,
1063
        $calendar_state,
1064
        $announcements_state,
1065
        $forum_state,
1066
        $wiki_state,
1067
        $chat_state,
1068
        $selfRegistrationAllowed,
1069
        $selfUnRegistrationAllowed,
1070
        $maximum_number_of_students,
1071
        $groups_per_user,
1072
        $documentAccess
1073
    ) {
1074
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
1075
        $id = (int) $id;
1076
1077
        $courseId = api_get_course_int_id();
1078
1079
        $allowDocumentAccess = api_get_configuration_value('group_category_document_access');
1080
        $documentCondition = '';
1081
        if ($allowDocumentAccess) {
1082
            $documentAccess = (int) $documentAccess;
1083
            $documentCondition = " document_access = $documentAccess, ";
1084
        }
1085
1086
        $sql = "UPDATE ".$table." SET
1087
                    title='".Database::escape_string($title)."',
1088
                    description='".Database::escape_string($description)."',
1089
                    doc_state = '".Database::escape_string($doc_state)."',
1090
                    work_state = '".Database::escape_string($work_state)."',
1091
                    calendar_state = '".Database::escape_string($calendar_state)."',
1092
                    announcements_state = '".Database::escape_string($announcements_state)."',
1093
                    forum_state = '".Database::escape_string($forum_state)."',
1094
                    wiki_state = '".Database::escape_string($wiki_state)."',
1095
                    chat_state = '".Database::escape_string($chat_state)."',
1096
                    groups_per_user   = '".Database::escape_string($groups_per_user)."',
1097
                    self_reg_allowed = '".Database::escape_string($selfRegistrationAllowed)."',
1098
                    self_unreg_allowed = '".Database::escape_string($selfUnRegistrationAllowed)."',
1099
                    $documentCondition
1100
                    max_student = ".intval($maximum_number_of_students)."
1101
                WHERE c_id = $courseId AND id = $id";
1102
1103
        Database::query($sql);
1104
1105
        // Updating all groups inside this category
1106
        $groups = self::get_group_list($id);
1107
1108
        if (!empty($groups)) {
1109
            foreach ($groups as $group) {
1110
                self::set_group_properties(
1111
                    $group['id'],
1112
                    $group['name'],
1113
                    $group['description'],
1114
                    $maximum_number_of_students,
1115
                    $doc_state,
1116
                    $work_state,
1117
                    $calendar_state,
1118
                    $announcements_state,
1119
                    $forum_state,
1120
                    $wiki_state,
1121
                    $chat_state,
1122
                    $selfRegistrationAllowed,
1123
                    $selfUnRegistrationAllowed,
1124
                    $id,
1125
                    $documentAccess
1126
                );
1127
            }
1128
        }
1129
    }
1130
1131
    /**
1132
     * Returns the number of groups of the user with the greatest number of
1133
     * subscriptions in the given category.
1134
     */
1135
    public static function get_current_max_groups_per_user(
1136
        $category_id = null,
1137
        $course_code = null
1138
    ) {
1139
        $course_info = api_get_course_info($course_code);
1140
        $group_table = Database::get_course_table(TABLE_GROUP);
1141
        $group_user_table = Database::get_course_table(TABLE_GROUP_USER);
1142
        $sql = 'SELECT COUNT(gu.group_id) AS current_max
1143
                FROM '.$group_user_table.' gu, '.$group_table.' g
1144
				WHERE g.c_id = '.$course_info['real_id'].'
1145
				AND gu.c_id = g.c_id
1146
				AND gu.group_id = g.iid ';
1147
        if (null != $category_id) {
1148
            $category_id = intval($category_id);
1149
            $sql .= ' AND g.category_id = '.$category_id;
1150
        }
1151
        $sql .= ' GROUP BY gu.user_id ORDER BY current_max DESC LIMIT 1';
1152
        $res = Database::query($sql);
1153
        $obj = Database::fetch_object($res);
1154
1155
        return $obj->current_max;
1156
    }
1157
1158
    /**
1159
     * Swaps the display-order of two categories.
1160
     *
1161
     * @param int $id1 The id of the first category
1162
     * @param int $id2 The id of the second category
1163
     */
1164
    public static function swap_category_order($id1, $id2)
1165
    {
1166
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
1167
        $id1 = intval($id1);
1168
        $id2 = intval($id2);
1169
        $course_id = api_get_course_int_id();
1170
1171
        $sql = "SELECT id, display_order FROM $table
1172
                WHERE id IN ($id1,$id2) AND c_id = $course_id ";
1173
        $res = Database::query($sql);
1174
        $cat1 = Database::fetch_object($res);
1175
        $cat2 = Database::fetch_object($res);
1176
        if ($cat1 && $cat2) {
1177
            $sql = "UPDATE $table SET display_order=$cat2->display_order
1178
                    WHERE id = $cat1->id AND c_id = $course_id ";
1179
            Database::query($sql);
1180
1181
            $sql = "UPDATE $table SET display_order=$cat1->display_order
1182
                    WHERE id = $cat2->id AND c_id = $course_id ";
1183
            Database::query($sql);
1184
        }
1185
    }
1186
1187
    /**
1188
     * Get all users from a given group.
1189
     *
1190
     * @param int  $group_id        The group
1191
     * @param bool $load_extra_info
1192
     * @param int  $start
1193
     * @param int  $limit
1194
     * @param bool $getCount
1195
     * @param int  $courseId
1196
     * @param $column
1197
     * @param $direction
1198
     *
1199
     * @return array list of user id
1200
     */
1201
    public static function get_users(
1202
        $group_id,
1203
        $load_extra_info = false,
1204
        $start = null,
1205
        $limit = null,
1206
        $getCount = false,
1207
        $courseId = null,
1208
        $column = null,
1209
        $direction = null
1210
    ) {
1211
        $group_user_table = Database::get_course_table(TABLE_GROUP_USER);
1212
        $groupTable = Database::get_course_table(TABLE_GROUP);
1213
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
1214
        $group_id = intval($group_id);
1215
1216
        if (empty($courseId)) {
1217
            $courseId = api_get_course_int_id();
1218
        } else {
1219
            $courseId = intval($courseId);
1220
        }
1221
1222
        $select = " SELECT u.id, firstname, lastname ";
1223
        if ($getCount) {
1224
            $select = " SELECT count(u.id) count";
1225
        }
1226
        $sql = "$select
1227
                FROM $group_user_table gu
1228
                INNER JOIN $groupTable g
1229
                ON (gu.group_id = g.id and g.c_id = gu.c_id)
1230
                INNER JOIN $user_table u
1231
                ON (u.id = gu.user_id)
1232
                WHERE
1233
                    gu.c_id = $courseId AND
1234
                    g.id = $group_id";
1235
1236
        if (!empty($column) && !empty($direction)) {
1237
            $column = Database::escape_string($column);
1238
            $columns = ['id', 'firstname', 'lastname'];
1239
            $column = in_array($column, $columns) ? $column : 'lastname';
1240
            $direction = ('ASC' === $direction ? 'ASC' : 'DESC');
1241
            $sql .= " ORDER BY $column $direction";
1242
        }
1243
1244
        if (!empty($start) && !empty($limit)) {
1245
            $start = (int) $start;
1246
            $limit = (int) $limit;
1247
            $sql .= " LIMIT $start, $limit";
1248
        }
1249
        $res = Database::query($sql);
1250
        $users = [];
1251
        while ($obj = Database::fetch_object($res)) {
1252
            if ($getCount) {
1253
                return $obj->count;
1254
                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...
1255
            }
1256
            if ($load_extra_info) {
1257
                $users[] = api_get_user_info($obj->id);
1258
            } else {
1259
                $users[] = $obj->id;
1260
            }
1261
        }
1262
1263
        return $users;
1264
    }
1265
1266
    /**
1267
     * @param int $group_id id
1268
     *
1269
     * @return array
1270
     */
1271
    public static function getStudentsAndTutors($group_id)
1272
    {
1273
        $group_user_table = Database::get_course_table(TABLE_GROUP_USER);
1274
        $tutor_user_table = Database::get_course_table(TABLE_GROUP_TUTOR);
1275
        $groupTable = Database::get_course_table(TABLE_GROUP);
1276
1277
        $course_id = api_get_course_int_id();
1278
        $group_id = intval($group_id);
1279
        $sql = "SELECT user_id
1280
                FROM $group_user_table gu
1281
                INNER JOIN $groupTable g
1282
                ON (gu.group_id = g.iid and g.c_id = gu.c_id)
1283
                WHERE gu.c_id = $course_id AND g.id = $group_id";
1284
        $res = Database::query($sql);
1285
        $users = [];
1286
1287
        while ($obj = Database::fetch_object($res)) {
1288
            $users[] = api_get_user_info($obj->user_id);
1289
        }
1290
1291
        $sql = "SELECT user_id
1292
                FROM $tutor_user_table gu
1293
                INNER JOIN $groupTable g
1294
                ON (gu.group_id = g.id and g.c_id = gu.c_id)
1295
                WHERE gu.c_id = $course_id AND g.id = $group_id";
1296
        $res = Database::query($sql);
1297
        while ($obj = Database::fetch_object($res)) {
1298
            $users[] = api_get_user_info($obj->user_id);
1299
        }
1300
1301
        return $users;
1302
    }
1303
1304
    /**
1305
     * Get only tutors from a group.
1306
     *
1307
     * @param array $groupInfo
1308
     *
1309
     * @return array
1310
     */
1311
    public static function getTutors($groupInfo)
1312
    {
1313
        $groupTable = Database::get_course_table(TABLE_GROUP);
1314
        $tutor_user_table = Database::get_course_table(TABLE_GROUP_TUTOR);
1315
        $course_id = api_get_course_int_id();
1316
        $group_id = intval($groupInfo['iid']);
1317
1318
        $sql = "SELECT user_id
1319
                FROM $tutor_user_table gu
1320
                INNER JOIN $groupTable g
1321
                ON (gu.group_id = g.id and g.c_id = gu.c_id)
1322
                WHERE gu.c_id = $course_id AND g.iid = $group_id";
1323
        $res = Database::query($sql);
1324
1325
        $users = [];
1326
        while ($obj = Database::fetch_object($res)) {
1327
            $users[] = api_get_user_info($obj->user_id);
1328
        }
1329
1330
        return $users;
1331
    }
1332
1333
    /**
1334
     * Get only students from a group (not tutors).
1335
     *
1336
     * @param int  $group_id         iid
1337
     * @param bool $filterOnlyActive
1338
     *
1339
     * @return array
1340
     */
1341
    public static function getStudents($group_id, $filterOnlyActive = false)
1342
    {
1343
        $activeCondition = $filterOnlyActive ? 'AND u.active = 1' : '';
1344
1345
        $em = Database::getManager();
1346
        $subscriptions = $em
1347
            ->createQuery("
1348
                SELECT u.id FROM ChamiloUserBundle:User u
1349
                INNER JOIN ChamiloCourseBundle:CGroupRelUser gu
1350
                    WITH u.id = gu.userId
1351
                INNER JOIN ChamiloCourseBundle:CGroupInfo g
1352
                WITH gu.groupId = g.id AND g.cId = gu.cId
1353
                WHERE gu.cId = :course AND g.id = :group
1354
                    $activeCondition
1355
            ")
1356
            ->setParameters([
1357
                'course' => api_get_course_int_id(),
1358
                'group' => intval($group_id),
1359
            ])
1360
            ->getResult();
1361
1362
        $users = [];
1363
        /** @var CGroupRelUser $subscription */
1364
        foreach ($subscriptions as $subscription) {
1365
            $users[] = api_get_user_info($subscription['id']);
1366
        }
1367
1368
        return $users;
1369
    }
1370
1371
    /**
1372
     * Returns users belonging to any of the group.
1373
     *
1374
     * @param array $groups list of group ids
1375
     *
1376
     * @return array list of user ids
1377
     */
1378
    public static function get_groups_users($groups = [])
1379
    {
1380
        $result = [];
1381
        $table = Database::get_course_table(TABLE_GROUP_USER);
1382
        $course_id = api_get_course_int_id();
1383
1384
        $groups = array_map('intval', $groups);
1385
        // protect individual elements with surrounding quotes
1386
        $groups = implode(', ', $groups);
1387
        $sql = "SELECT DISTINCT user_id
1388
                FROM $table gu
1389
                WHERE c_id = $course_id AND gu.group_id IN ($groups)";
1390
        $rs = Database::query($sql);
1391
        while ($row = Database::fetch_array($rs)) {
1392
            $result[] = $row['user_id'];
1393
        }
1394
1395
        return $result;
1396
    }
1397
1398
    /**
1399
     * Fill the groups with students.
1400
     * The algorithm takes care to first fill the groups with the least # of users.
1401
     * Analysis
1402
     * There was a problem with the "ALL" setting.
1403
     * When max # of groups is set to all, the value is sometimes NULL and sometimes ALL
1404
     * and in both cased the query does not work as expected.
1405
     * Stupid solution (currently implemented: set ALL to a big number (INFINITE) and things are solved :)
1406
     * Better solution: that's up to you.
1407
     *
1408
     * Note
1409
     * Throughout Dokeos there is some confusion about "course id" and "course code"
1410
     * The code is e.g. TEST101, but sometimes a variable that is called courseID also contains a course code string.
1411
     * However, there is also a integer course_id that uniquely identifies the course.
1412
     * ywarnier:> Now the course_id has been removed (25/1/2005)
1413
     * The databases are als very inconsistent in this.
1414
     *
1415
     * @param array $groupInfo
1416
     *
1417
     * @author Chrisptophe Gesche <[email protected]>,
1418
     *         Hugues Peeters     <[email protected]> - original version
1419
     * @author Roan Embrechts - virtual course support, code cleaning
1420
     * @author Bart Mollet - code cleaning, use other GroupManager-functions
1421
     *
1422
     * @return bool
1423
     */
1424
    public static function fillGroupWithUsers($groupInfo)
1425
    {
1426
        $_course = api_get_course_info();
1427
        if (empty($_course) || empty($groupInfo)) {
1428
            return false;
1429
        }
1430
        $session_id = api_get_session_id();
1431
        $complete_user_list = CourseManager::get_user_list_from_course_code(
1432
            $_course['code'],
1433
            $session_id
1434
        );
1435
        $groupIid = $groupInfo['iid'];
1436
        $category = self::get_category_from_group($groupIid);
1437
1438
        // Getting max numbers of user from group
1439
        $maxNumberStudents = empty($groupInfo['maximum_number_of_students']) ? self::INFINITE : $groupInfo['maximum_number_of_students'];
1440
        $groupsPerUser = self::INFINITE;
1441
        $categoryId = 0;
1442
        if ($category) {
1443
            $groupsPerUser = empty($category['groups_per_user']) ? self::INFINITE : $category['groups_per_user'];
1444
            $maxNumberStudentsCategory = empty($category['max_student']) ? self::INFINITE : $category['max_student'];
1445
            $categoryId = $category['id'];
1446
            if ($maxNumberStudentsCategory < $maxNumberStudents) {
1447
                $maxNumberStudents = $maxNumberStudentsCategory;
1448
            }
1449
        }
1450
1451
        $usersToAdd = [];
1452
        foreach ($complete_user_list as $userInfo) {
1453
            $isSubscribed = self::is_subscribed($userInfo['user_id'], $groupInfo);
1454
            if ($isSubscribed) {
1455
                continue;
1456
            }
1457
            $numberOfGroups = self::user_in_number_of_groups(
1458
                $userInfo['user_id'],
1459
                $categoryId
1460
            );
1461
            if ($groupsPerUser > $numberOfGroups) {
1462
                $usersToAdd[] = $userInfo['user_id'];
1463
            }
1464
            if (count($usersToAdd) == $maxNumberStudents) {
1465
                break;
1466
            }
1467
        }
1468
1469
        foreach ($usersToAdd as $userId) {
1470
            self::subscribe_users($userId, $groupInfo);
1471
        }
1472
    }
1473
1474
    /**
1475
     * Get the number of students in a group.
1476
     *
1477
     * @param int $group_id id
1478
     *
1479
     * @return int number of students in the given group
1480
     */
1481
    public static function number_of_students($group_id, $course_id = null)
1482
    {
1483
        $table = Database::get_course_table(TABLE_GROUP_USER);
1484
        $group_id = (int) $group_id;
1485
        $course_id = (int) $course_id;
1486
1487
        if (empty($course_id)) {
1488
            $course_id = api_get_course_int_id();
1489
        }
1490
        $sql = "SELECT COUNT(*) AS number_of_students
1491
                FROM $table
1492
                WHERE c_id = $course_id AND group_id = $group_id";
1493
        $result = Database::query($sql);
1494
        $db_object = Database::fetch_object($result);
1495
1496
        return $db_object->number_of_students;
1497
    }
1498
1499
    /**
1500
     * Maximum number of students in a group.
1501
     *
1502
     * @param int $group_id iid
1503
     *
1504
     * @return int maximum number of students in the given group
1505
     */
1506
    public static function maximum_number_of_students($group_id)
1507
    {
1508
        $table = Database::get_course_table(TABLE_GROUP);
1509
        $group_id = (int) $group_id;
1510
        $course_id = api_get_course_int_id();
1511
        $sql = "SELECT max_student FROM $table
1512
                WHERE c_id = $course_id AND iid = $group_id";
1513
        $db_result = Database::query($sql);
1514
        $db_object = Database::fetch_object($db_result);
1515
        if (0 == $db_object->max_student) {
1516
            return self::INFINITE;
1517
        }
1518
1519
        return $db_object->max_student;
1520
    }
1521
1522
    /**
1523
     * Number of groups of a user.
1524
     *
1525
     * @param int $user_id
1526
     * @param int $cat_id
1527
     *
1528
     * @return int the number of groups the user is subscribed in
1529
     */
1530
    public static function user_in_number_of_groups($user_id, $cat_id = 0)
1531
    {
1532
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1533
        $table_group = Database::get_course_table(TABLE_GROUP);
1534
        $user_id = (int) $user_id;
1535
        $cat_id = (int) $cat_id;
1536
1537
        $course_id = api_get_course_int_id();
1538
        $cat_condition = '';
1539
        if (!empty($cat_id)) {
1540
            $cat_condition = " AND g.category_id =  $cat_id ";
1541
        }
1542
1543
        $sql = "SELECT COUNT(*) AS number_of_groups
1544
                FROM $table_group_user gu
1545
                INNER JOIN $table_group g
1546
                ON (g.iid = gu.group_id AND gu.c_id = g.c_id)
1547
                WHERE
1548
                    gu.c_id = $course_id AND
1549
                    g.c_id = $course_id AND
1550
                    gu.user_id = $user_id
1551
                    $cat_condition";
1552
1553
        $result = Database::query($sql);
1554
        $db_object = Database::fetch_object($result);
1555
1556
        return $db_object->number_of_groups;
1557
    }
1558
1559
    /**
1560
     * Is sef-registration allowed?
1561
     *
1562
     * @param int   $user_id
1563
     * @param array $groupInfo
1564
     *
1565
     * @return bool TRUE if self-registration is allowed in the given group
1566
     */
1567
    public static function is_self_registration_allowed($user_id, $groupInfo)
1568
    {
1569
        $course_id = api_get_course_int_id();
1570
        if (empty($user_id)) {
1571
            return false;
1572
        }
1573
1574
        $groupIid = $groupInfo['iid'];
1575
        $table = Database::get_course_table(TABLE_GROUP);
1576
        if (isset($groupIid)) {
1577
            $sql = "SELECT status, self_registration_allowed
1578
                    FROM $table
1579
                    WHERE c_id = $course_id AND iid = $groupIid";
1580
            $result = Database::query($sql);
1581
            $group = Database::fetch_object($result);
1582
1583
            if ($group->status == 0 || $group->self_registration_allowed != 1) {
1584
                return false;
1585
            }
1586
1587
            return self::canUserSubscribe($user_id, $groupInfo);
1588
        }
1589
1590
        return false;
1591
    }
1592
1593
    /**
1594
     * Is sef-unregistration allowed?
1595
     *
1596
     * @param int   $user_id
1597
     * @param array $groupInfo
1598
     *
1599
     * @return bool TRUE if self-unregistration is allowed in the given group
1600
     */
1601
    public static function is_self_unregistration_allowed($user_id, $groupInfo)
1602
    {
1603
        if (empty($user_id) || empty($groupInfo)) {
1604
            return false;
1605
        }
1606
        $groupIid = $groupInfo['iid'];
1607
        $table = Database::get_course_table(TABLE_GROUP);
1608
        $course_id = api_get_course_int_id();
1609
1610
        $sql = "SELECT status, self_unregistration_allowed
1611
                FROM $table
1612
                WHERE c_id = $course_id AND iid = $groupIid";
1613
        $result = Database::query($sql);
1614
        $group = Database::fetch_object($result);
1615
1616
        if ($group->status == 0 || $group->self_unregistration_allowed != 1) {
1617
            return false;
1618
        }
1619
1620
        return self::is_subscribed($user_id, $groupInfo);
1621
    }
1622
1623
    /**
1624
     * Is user subscribed in group?
1625
     *
1626
     * @param int   $user_id
1627
     * @param array $groupInfo
1628
     *
1629
     * @return bool TRUE if given user is subscribed in given group
1630
     */
1631
    public static function is_subscribed($user_id, $groupInfo)
1632
    {
1633
        $course_id = api_get_course_int_id();
1634
        if (empty($user_id) || empty($groupInfo) || empty($course_id)) {
1635
            return false;
1636
        }
1637
        $table = Database::get_course_table(TABLE_GROUP_USER);
1638
        $group_id = (int) $groupInfo['id'];
1639
        $user_id = (int) $user_id;
1640
1641
        $sql = "SELECT 1 FROM $table
1642
                WHERE
1643
                    c_id = $course_id AND
1644
                    group_id = $group_id AND
1645
                    user_id = $user_id
1646
                ";
1647
        $result = Database::query($sql);
1648
1649
        return Database::num_rows($result) > 0;
1650
    }
1651
1652
    /**
1653
     * Can a user subscribe to a specified group in a course.
1654
     *
1655
     * @param int   $user_id
1656
     * @param array $groupInfo
1657
     * @param bool  $checkMaxNumberStudents
1658
     *
1659
     * @return bool TRUE if given user  can be subscribed in given group
1660
     */
1661
    public static function canUserSubscribe(
1662
        $user_id,
1663
        $groupInfo,
1664
        $checkMaxNumberStudents = true
1665
    ) {
1666
        $group_id = $groupInfo['id'];
1667
        $groupIid = $groupInfo['iid'];
1668
        if ($checkMaxNumberStudents) {
1669
            $category = self::get_category_from_group($groupIid);
1670
            if ($category) {
1671
                if ($category['groups_per_user'] == self::GROUP_PER_MEMBER_NO_LIMIT) {
1672
                    $category['groups_per_user'] = self::INFINITE;
1673
                }
1674
                $result = self::user_in_number_of_groups($user_id, $category['id']) < $category['groups_per_user'];
1675
                if ($result == false) {
1676
                    return false;
1677
                }
1678
            }
1679
1680
            $result = self::number_of_students($group_id) < self::maximum_number_of_students($groupIid);
1681
1682
            if ($result == false) {
1683
                return false;
1684
            }
1685
        }
1686
1687
        $result = self::is_tutor_of_group($user_id, $groupInfo);
1688
1689
        if ($result) {
1690
            return false;
1691
        }
1692
1693
        $result = self::is_subscribed($user_id, $groupInfo);
1694
1695
        if ($result) {
1696
            return false;
1697
        }
1698
1699
        return true;
1700
    }
1701
1702
    /**
1703
     * Get all subscribed users (members) from a group.
1704
     *
1705
     * @param array $groupInfo
1706
     *
1707
     * @return array An array with information of all users from the given group.
1708
     *               (user_id, firstname, lastname, email)
1709
     */
1710
    public static function get_subscribed_users($groupInfo)
1711
    {
1712
        if (empty($groupInfo)) {
1713
            return [];
1714
        }
1715
1716
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
1717
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1718
        $order_clause = api_sort_by_first_name() ? ' ORDER BY u.firstname, u.lastname' : ' ORDER BY u.lastname, u.firstname';
1719
        $orderListByOfficialCode = api_get_setting('order_user_list_by_official_code');
1720
        if ($orderListByOfficialCode === 'true') {
1721
            $order_clause = ' ORDER BY u.official_code, u.firstname, u.lastname';
1722
        }
1723
1724
        $group_id = (int) $groupInfo['iid'];
1725
1726
        if (empty($group_id)) {
1727
            return [];
1728
        }
1729
1730
        $course_id = api_get_course_int_id();
1731
1732
        $sql = "SELECT
1733
                    ug.id,
1734
                    u.user_id,
1735
                    u.lastname,
1736
                    u.firstname,
1737
                    u.email,
1738
                    u.username
1739
                FROM $table_user u
1740
                INNER JOIN $table_group_user ug
1741
                ON (ug.user_id = u.user_id)
1742
                WHERE ug.c_id = $course_id AND
1743
                      ug.group_id = $group_id
1744
                $order_clause";
1745
1746
        $db_result = Database::query($sql);
1747
        $users = [];
1748
        while ($user = Database::fetch_object($db_result)) {
1749
            $users[$user->user_id] = [
1750
                'user_id' => $user->user_id,
1751
                'firstname' => $user->firstname,
1752
                'lastname' => $user->lastname,
1753
                'email' => $user->email,
1754
                'username' => $user->username,
1755
            ];
1756
        }
1757
1758
        return $users;
1759
    }
1760
1761
    /**
1762
     * @author Patrick Cool <[email protected]>, Ghent University
1763
     * Get all subscribed tutors of a group
1764
     *
1765
     * @param array $groupInfo
1766
     *
1767
     * @return array An array with information of all users from the given group.
1768
     *               (user_id, firstname, lastname, email)
1769
     */
1770
    public static function get_subscribed_tutors($groupInfo, $id_only = false)
1771
    {
1772
        if (empty($groupInfo)) {
1773
            return [];
1774
        }
1775
1776
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
1777
        $table_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
1778
        $order_clause = api_sort_by_first_name() ? ' ORDER BY u.firstname, u.lastname' : ' ORDER BY u.lastname, u.firstname';
1779
1780
        $orderListByOfficialCode = api_get_setting('order_user_list_by_official_code');
1781
        if ($orderListByOfficialCode === 'true') {
1782
            $order_clause = ' ORDER BY u.official_code, u.firstname, u.lastname';
1783
        }
1784
1785
        $group_id = (int) $groupInfo['iid'];
1786
        $course_id = api_get_course_int_id();
1787
1788
        $sql = "SELECT tg.id, u.user_id, u.lastname, u.firstname, u.email
1789
                FROM $table_user u, $table_group_tutor tg
1790
                WHERE
1791
                    tg.c_id = $course_id AND
1792
                    tg.group_id = $group_id AND
1793
                    tg.user_id = u.user_id
1794
                $order_clause
1795
                ";
1796
        $db_result = Database::query($sql);
1797
        $users = [];
1798
        while ($user = Database::fetch_object($db_result)) {
1799
            if (!$id_only) {
1800
                $member['user_id'] = $user->user_id;
1801
                $member['firstname'] = $user->firstname;
1802
                $member['lastname'] = $user->lastname;
1803
                $member['email'] = $user->email;
1804
                $users[] = $member;
1805
            } else {
1806
                $users[] = $user->user_id;
1807
            }
1808
        }
1809
1810
        return $users;
1811
    }
1812
1813
    /**
1814
     * Subscribe user(s) to a specified group in current course (as a student).
1815
     *
1816
     * @param mixed $user_ids  Can be an array with user-id's or a single user-id
1817
     * @param array $groupInfo
1818
     * @param int   $course_id
1819
     *
1820
     * @return bool TRUE if successful
1821
     */
1822
    public static function subscribe_users($user_ids, $groupInfo, $course_id = null)
1823
    {
1824
        $user_ids = is_array($user_ids) ? $user_ids : [$user_ids];
1825
        $course_id = empty($course_id) ? api_get_course_int_id() : (int) $course_id;
1826
        $group_id = $groupInfo['id'];
1827
1828
        if (!empty($user_ids)) {
1829
            $table = Database::get_course_table(TABLE_GROUP_USER);
1830
            foreach ($user_ids as $user_id) {
1831
                if (self::canUserSubscribe($user_id, $groupInfo)) {
1832
                    $user_id = (int) $user_id;
1833
                    $sql = "INSERT INTO ".$table." (c_id, user_id, group_id)
1834
                            VALUES ('$course_id', '".$user_id."', '".$group_id."')";
1835
                    Database::query($sql);
1836
                }
1837
            }
1838
        }
1839
1840
        return true;
1841
    }
1842
1843
    /**
1844
     * Subscribe tutor(s) to a specified group in current course.
1845
     *
1846
     * @param mixed $user_ids  Can be an array with user-id's or a single user-id
1847
     * @param array $groupInfo
1848
     * @param int   $course_id
1849
     *
1850
     * @author Patrick Cool <[email protected]>, Ghent University
1851
     *
1852
     * @see subscribe_users. This function is almost an exact copy of that function.
1853
     *
1854
     * @return bool TRUE if successful
1855
     */
1856
    public static function subscribe_tutors($user_ids, $groupInfo, $course_id = 0)
1857
    {
1858
        $user_ids = is_array($user_ids) ? $user_ids : [$user_ids];
1859
        $result = true;
1860
        $course_id = isset($course_id) && !empty($course_id) ? intval($course_id) : api_get_course_int_id();
1861
        $table_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
1862
        $groupId = (int) $groupInfo['id'];
1863
1864
        foreach ($user_ids as $user_id) {
1865
            $user_id = intval($user_id);
1866
            if (self::canUserSubscribe($user_id, $groupInfo, false)) {
1867
                $sql = "INSERT INTO ".$table_group_tutor." (c_id, user_id, group_id)
1868
                        VALUES ('$course_id', '".$user_id."', '".$groupId."')";
1869
                $result = Database::query($sql);
1870
            }
1871
        }
1872
1873
        return $result;
1874
    }
1875
1876
    /**
1877
     * Unsubscribe user(s) from a specified group in current course.
1878
     *
1879
     * @param mixed $user_ids  Can be an array with user-id's or a single user-id
1880
     * @param array $groupInfo
1881
     *
1882
     * @return bool TRUE if successful
1883
     */
1884
    public static function unsubscribe_users($user_ids, $groupInfo)
1885
    {
1886
        $user_ids = is_array($user_ids) ? $user_ids : [$user_ids];
1887
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1888
        $group_id = intval($groupInfo['id']);
1889
        $course_id = api_get_course_int_id();
1890
        $sql = 'DELETE FROM '.$table_group_user.'
1891
                WHERE
1892
                    c_id = '.$course_id.' AND
1893
                    group_id = '.$group_id.' AND
1894
                    user_id IN ('.implode(',', $user_ids).')
1895
                ';
1896
        Database::query($sql);
1897
    }
1898
1899
    /**
1900
     * Unsubscribe all users from one or more groups.
1901
     *
1902
     * @param array $groupInfo
1903
     *
1904
     * @return bool TRUE if successful
1905
     */
1906
    public static function unsubscribe_all_users($groupInfo)
1907
    {
1908
        $course_id = api_get_course_int_id();
1909
        $groupId = (int) $groupInfo['id'];
1910
        if (empty($course_id) || empty($groupId)) {
1911
            return false;
1912
        }
1913
1914
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1915
        $sql = "DELETE FROM $table_group_user
1916
                WHERE
1917
                    group_id = $groupId AND
1918
                    c_id = $course_id";
1919
        $result = Database::query($sql);
1920
1921
        return $result;
1922
    }
1923
1924
    /**
1925
     * Unsubscribe all tutors from one or more groups.
1926
     *
1927
     * @param int $groupId iid
1928
     *
1929
     * @see unsubscribe_all_users. This function is almost an exact copy of that function.
1930
     *
1931
     * @return bool TRUE if successful
1932
     *
1933
     * @author Patrick Cool <[email protected]>, Ghent University
1934
     */
1935
    public static function unsubscribe_all_tutors($groupId)
1936
    {
1937
        $courseId = api_get_course_int_id();
1938
        $groupId = (int) $groupId;
1939
1940
        if (empty($courseId) || empty($groupId)) {
1941
            return false;
1942
        }
1943
1944
        if (!empty($groupId)) {
1945
            $table_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
1946
            $sql = "DELETE FROM $table_group_tutor
1947
                    WHERE group_id = $groupId AND c_id = $courseId";
1948
            $result = Database::query($sql);
1949
1950
            return $result;
1951
        }
1952
1953
        return true;
1954
    }
1955
1956
    /**
1957
     * Is the user a tutor of this group?
1958
     *
1959
     * @param int   $user_id   the id of the user
1960
     * @param array $groupInfo
1961
     * @param int   $courseId
1962
     *
1963
     * @return bool true/false
1964
     *
1965
     * @todo use the function user_has_access that includes this function
1966
     *
1967
     * @author Patrick Cool <[email protected]>, Ghent University
1968
     */
1969
    public static function is_tutor_of_group($user_id, $groupInfo, $courseId = 0)
1970
    {
1971
        if (empty($groupInfo)) {
1972
            return false;
1973
        }
1974
1975
        $courseId = empty($courseId) ? api_get_course_int_id() : (int) $courseId;
1976
        if (empty($courseId)) {
1977
            return false;
1978
        }
1979
1980
        $user_id = (int) $user_id;
1981
        $group_id = (int) $groupInfo['id'];
1982
1983
        $table = Database::get_course_table(TABLE_GROUP_TUTOR);
1984
1985
        $sql = "SELECT * FROM $table
1986
                WHERE
1987
                    c_id = $courseId AND
1988
                    user_id = $user_id AND
1989
                    group_id = $group_id";
1990
        $result = Database::query($sql);
1991
        if (Database::num_rows($result) > 0) {
1992
            return true;
1993
        }
1994
1995
        return false;
1996
    }
1997
1998
    /**
1999
     * Is the user part of this group? This can be a tutor or a normal member
2000
     * you should use this function if the access to a tool or functionality is
2001
     * restricted to the people who are actually in the group
2002
     * before you had to check if the user was
2003
     * 1. a member of the group OR
2004
     * 2. a tutor of the group. This function combines both.
2005
     *
2006
     * @param int   $user_id   the id of the user
2007
     * @param array $groupInfo
2008
     *
2009
     * @return bool true/false
2010
     *
2011
     * @author Patrick Cool <[email protected]>, Ghent University
2012
     */
2013
    public static function is_user_in_group($user_id, $groupInfo)
2014
    {
2015
        $member = self::is_subscribed($user_id, $groupInfo);
2016
        if ($member) {
2017
            return true;
2018
        }
2019
2020
        $tutor = self::is_tutor_of_group($user_id, $groupInfo);
2021
        if ($tutor) {
2022
            return true;
2023
        }
2024
2025
        return false;
2026
    }
2027
2028
    /**
2029
     * Get all group's from a given course in which a given user is unsubscribed.
2030
     *
2031
     * @author  Patrick Cool
2032
     *
2033
     * @param int $course_id retrieve the groups for
2034
     * @param int $user_id   the ID of the user you want to know all its group memberships
2035
     *
2036
     * @return array
2037
     */
2038
    public static function get_group_ids($course_id, $user_id)
2039
    {
2040
        $groups = [];
2041
        $tbl_group = Database::get_course_table(TABLE_GROUP_USER);
2042
        $tbl_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
2043
        $user_id = intval($user_id);
2044
        $course_id = intval($course_id);
2045
2046
        $sql = "SELECT group_id FROM $tbl_group
2047
                WHERE c_id = $course_id AND user_id = '$user_id'";
2048
        $result = Database::query($sql);
2049
2050
        if ($result) {
2051
            while ($row = Database::fetch_array($result)) {
2052
                $groups[] = $row['group_id'];
2053
            }
2054
        }
2055
2056
        //Also loading if i'm the tutor
2057
        $sql = "SELECT group_id FROM $tbl_group_tutor
2058
                WHERE c_id = $course_id AND user_id = '$user_id'";
2059
        $result = Database::query($sql);
2060
        if ($result) {
2061
            while ($row = Database::fetch_array($result)) {
2062
                $groups[] = $row['group_id'];
2063
            }
2064
        }
2065
        if (!empty($groups)) {
2066
            array_filter($groups);
2067
        }
2068
2069
        return $groups;
2070
    }
2071
2072
    /**
2073
     * Check if a user has access to a certain group tool.
2074
     *
2075
     * @param int    $user_id  The user id
2076
     * @param int    $group_id The group iid
2077
     * @param string $tool     The tool to check the access rights. This should be
2078
     *                         one of constants: GROUP_TOOL_DOCUMENTS
2079
     *
2080
     * @return bool true if the given user has access to the given tool in the
2081
     *              given course
2082
     */
2083
    public static function user_has_access($user_id, $group_id, $tool)
2084
    {
2085
        // Admin have access everywhere
2086
        if (api_is_platform_admin()) {
2087
            return true;
2088
        }
2089
2090
        // Course admin also have access to everything
2091
        if (api_is_allowed_to_edit(false, true, true)) {
2092
            return true;
2093
        }
2094
2095
        switch ($tool) {
2096
            case self::GROUP_TOOL_FORUM:
2097
                $key = 'forum_state';
2098
                break;
2099
            case self::GROUP_TOOL_DOCUMENTS:
2100
                $key = 'doc_state';
2101
                break;
2102
            case self::GROUP_TOOL_CALENDAR:
2103
                $key = 'calendar_state';
2104
                break;
2105
            case self::GROUP_TOOL_ANNOUNCEMENT:
2106
                $key = 'announcements_state';
2107
                break;
2108
            case self::GROUP_TOOL_WORK:
2109
                $key = 'work_state';
2110
                break;
2111
            case self::GROUP_TOOL_WIKI:
2112
                $key = 'wiki_state';
2113
                break;
2114
            case self::GROUP_TOOL_CHAT:
2115
                $key = 'chat_state';
2116
                break;
2117
            default:
2118
                return false;
2119
        }
2120
2121
        // Check group properties
2122
        $groupInfo = self::get_group_properties($group_id, true);
2123
2124
        if (empty($groupInfo)) {
2125
            return false;
2126
        }
2127
2128
        if ($groupInfo['status'] == 0) {
2129
            return false;
2130
        }
2131
2132
        if (!isset($groupInfo[$key])) {
2133
            return false;
2134
        }
2135
2136
        $status = $groupInfo[$key];
2137
2138
        switch ($status) {
2139
            case self::TOOL_NOT_AVAILABLE:
2140
                return false;
2141
                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...
2142
            case self::TOOL_PUBLIC:
2143
                return true;
2144
                break;
2145
            case self::TOOL_PRIVATE:
2146
                $userIsInGroup = self::is_user_in_group($user_id, $groupInfo);
2147
                if ($userIsInGroup) {
2148
                    return true;
2149
                }
2150
                break;
2151
            case self::TOOL_PRIVATE_BETWEEN_USERS:
2152
                // Only works for announcements for now
2153
                $userIsInGroup = self::is_user_in_group($user_id, $groupInfo);
2154
                if ($userIsInGroup && $tool == self::GROUP_TOOL_ANNOUNCEMENT) {
2155
                    return true;
2156
                }
2157
                break;
2158
        }
2159
2160
        return false;
2161
    }
2162
2163
    /**
2164
     * @param int   $userId
2165
     * @param array $groupInfo
2166
     * @param int   $sessionId
2167
     *
2168
     * @return bool
2169
     */
2170
    public static function userHasAccessToBrowse($userId, $groupInfo, $sessionId = 0)
2171
    {
2172
        if (empty($groupInfo)) {
2173
            return false;
2174
        }
2175
2176
        if (api_is_platform_admin()) {
2177
            return true;
2178
        }
2179
2180
        if (api_is_allowed_to_edit(false, true, true)) {
2181
            return true;
2182
        }
2183
2184
        if (!empty($sessionId)) {
2185
            if (api_is_coach($sessionId, api_get_course_int_id())) {
2186
                return true;
2187
            }
2188
2189
            if (api_is_drh()) {
2190
                if (SessionManager::isUserSubscribedAsHRM($sessionId, $userId)) {
2191
                    return true;
2192
                }
2193
            }
2194
        }
2195
2196
        $groupId = $groupInfo['iid'];
2197
        if (self::is_tutor_of_group($userId, $groupInfo)) {
2198
            return true;
2199
        }
2200
2201
        if ($groupInfo['status'] == 0) {
2202
            return false;
2203
        }
2204
2205
        if (self::user_has_access($userId, $groupId, self::GROUP_TOOL_FORUM) ||
2206
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_DOCUMENTS) ||
2207
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_CALENDAR) ||
2208
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_ANNOUNCEMENT) ||
2209
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_WORK) ||
2210
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_WIKI) ||
2211
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_CHAT)
2212
        ) {
2213
            return true;
2214
        }
2215
2216
        if (api_is_session_general_coach() && $groupInfo['session_id'] == $sessionId) {
2217
            return true;
2218
        }
2219
2220
        return false;
2221
    }
2222
2223
    /**
2224
     * Get all groups where a specific user is subscribed.
2225
     *
2226
     * @param int $user_id
2227
     *
2228
     * @return array
2229
     */
2230
    public static function get_user_group_name($user_id)
2231
    {
2232
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
2233
        $table_group = Database::get_course_table(TABLE_GROUP);
2234
        $user_id = intval($user_id);
2235
        $course_id = api_get_course_int_id();
2236
        $sql = "SELECT name
2237
                FROM $table_group g
2238
                INNER JOIN $table_group_user gu
2239
                ON (gu.group_id = g.iid)
2240
                WHERE
2241
                  gu.c_id= $course_id AND
2242
                  g.c_id= $course_id AND
2243
                  gu.user_id = $user_id";
2244
        $res = Database::query($sql);
2245
        $groups = [];
2246
        while ($group = Database::fetch_array($res)) {
2247
            $groups[] .= $group['name'];
2248
        }
2249
2250
        return $groups;
2251
    }
2252
2253
    /**
2254
     * Get all groups where a specific user is subscribed.
2255
     *
2256
     * @param int      $user_id
2257
     * @param int      $courseId
2258
     * @param int|null $sessionId
2259
     *
2260
     * @return array
2261
     */
2262
    public static function getAllGroupPerUserSubscription($user_id, $courseId = 0, $sessionId = null)
2263
    {
2264
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
2265
        $table_tutor_user = Database::get_course_table(TABLE_GROUP_TUTOR);
2266
        $table_group = Database::get_course_table(TABLE_GROUP);
2267
        $user_id = (int) $user_id;
2268
        $courseId = empty($courseId) ? api_get_course_int_id() : (int) $courseId;
2269
2270
        $sql = "SELECT DISTINCT g.*
2271
               FROM $table_group g
2272
               LEFT JOIN $table_group_user gu
2273
               ON (gu.group_id = g.iid AND g.c_id = gu.c_id)
2274
               LEFT JOIN $table_tutor_user tu
2275
               ON (tu.group_id = g.iid AND g.c_id = tu.c_id)
2276
               WHERE
2277
                  g.c_id = $courseId AND
2278
                  (gu.user_id = $user_id OR tu.user_id = $user_id) ";
2279
2280
        if (null !== $sessionId) {
2281
            $sessionId = (int) $sessionId;
2282
            $sql .= " AND g.session_id = $sessionId ";
2283
        }
2284
2285
        $res = Database::query($sql);
2286
        $groups = [];
2287
        while ($group = Database::fetch_array($res, 'ASSOC')) {
2288
            $groups[] = $group;
2289
        }
2290
2291
        return $groups;
2292
    }
2293
2294
    /**
2295
     * @param array $group_list
2296
     * @param int   $category_id
2297
     *
2298
     * @return string
2299
     */
2300
    public static function process_groups($group_list, $category_id = 0)
2301
    {
2302
        $charset = 'UTF-8';
2303
        $category_id = (int) $category_id;
2304
        $totalRegistered = 0;
2305
        $group_data = [];
2306
        $user_info = api_get_user_info();
2307
        $session_id = api_get_session_id();
2308
        $user_id = $user_info['user_id'];
2309
        $hideGroup = api_get_setting('hide_course_group_if_no_tools_available');
2310
        $extraField = new ExtraField('survey');
2311
        $surveyGroupExists = $extraField->get_handler_field_info_by_field_variable('group_id') ? true : false;
2312
        $url = api_get_path(WEB_CODE_PATH).'group/';
2313
2314
        foreach ($group_list as $this_group) {
2315
            // Validation when belongs to a session
2316
            $session_img = api_get_session_image($this_group['session_id'], $user_info['status']);
2317
2318
            // All the tutors of this group
2319
            $tutors = self::get_subscribed_tutors($this_group, true);
2320
            $isMember = self::is_subscribed($user_id, $this_group);
2321
2322
            // Create a new table-row
2323
            $row = [];
2324
            // Checkbox
2325
            if (api_is_allowed_to_edit(false, true) && count($group_list) > 1) {
2326
                $row[] = $this_group['id'];
2327
            }
2328
2329
            if (self::userHasAccessToBrowse($user_id, $this_group, $session_id)) {
2330
                // Group name
2331
                $groupNameClass = null;
2332
                if (0 == $this_group['status']) {
2333
                    $groupNameClass = 'muted';
2334
                }
2335
2336
                $group_name = '<a class="'.$groupNameClass.'" href="group_space.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'">'.
2337
                    Security::remove_XSS($this_group['name']).'</a> ';
2338
2339
                $group_name2 = '';
2340
                if (api_get_configuration_value('extra')) {
2341
                    $group_name2 = '<a href="group_space_tracking.php?cidReq='.api_get_course_id().'&gidReq='
2342
                        .$this_group['id'].'">'.get_lang('suivi_de').''.stripslashes($this_group['name']).'</a>';
2343
                }
2344
2345
                if (!empty($user_id) && !empty($this_group['id_tutor']) && $user_id == $this_group['id_tutor']) {
2346
                    $group_name .= Display::label(get_lang('OneMyGroups'), 'success');
2347
                } elseif ($isMember) {
2348
                    $group_name .= Display::label(get_lang('MyGroup'), 'success');
2349
                }
2350
2351
                if (api_is_allowed_to_edit() && !empty($this_group['session_name'])) {
2352
                    $group_name .= ' ('.$this_group['session_name'].')';
2353
                }
2354
                $group_name .= $session_img;
2355
                $row[] = $group_name.$group_name2.'<br />'.stripslashes(trim($this_group['description']));
2356
            } else {
2357
                if ('true' === $hideGroup) {
2358
                    continue;
2359
                }
2360
                $row[] = $this_group['name'].'<br />'.stripslashes(trim($this_group['description']));
2361
            }
2362
2363
            // Tutor name
2364
            $tutor_info = '';
2365
            if (count($tutors) > 0) {
2366
                foreach ($tutors as $tutor_id) {
2367
                    $tutor = api_get_user_info($tutor_id);
2368
                    $username = api_htmlentities(
2369
                        sprintf(get_lang('LoginX'), $tutor['username']),
2370
                        ENT_QUOTES
2371
                    );
2372
                    if ('true' === api_get_setting('show_email_addresses')) {
2373
                        $tutor_info .= Display::tag(
2374
                            'span',
2375
                            Display::encrypted_mailto_link(
2376
                                $tutor['mail'],
2377
                                $tutor['complete_name']
2378
                            ),
2379
                            ['title' => $username]
2380
                        ).', ';
2381
                    } else {
2382
                        if (api_is_allowed_to_edit()) {
2383
                            $tutor_info .= Display::tag(
2384
                            'span',
2385
                                Display::encrypted_mailto_link(
2386
                                    $tutor['mail'],
2387
                                    $tutor['complete_name_with_username']
2388
                                ),
2389
                                ['title' => $username]
2390
                            ).', ';
2391
                        } else {
2392
                            $tutor_info .= Display::tag(
2393
                                'span',
2394
                                $tutor['complete_name'],
2395
                                ['title' => $username]
2396
                            ).', ';
2397
                        }
2398
                    }
2399
                }
2400
            }
2401
2402
            $tutor_info = api_substr(
2403
                $tutor_info,
2404
                0,
2405
                api_strlen($tutor_info) - 2
2406
            );
2407
            $row[] = $tutor_info;
2408
2409
            // Max number of members in group
2410
            $max_members = $this_group['maximum_number_of_members'] == self::MEMBER_PER_GROUP_NO_LIMIT ? ' ' : ' / '.$this_group['maximum_number_of_members'];
2411
2412
            // Number of members in group
2413
            $row[] = $this_group['number_of_members'].$max_members;
2414
2415
            // Self-registration / unregistration
2416
            if (!api_is_allowed_to_edit(false, true)) {
2417
                if (self::is_self_registration_allowed($user_id, $this_group)) {
2418
                    $row[] = '<a class = "btn btn-default"
2419
                        href="group.php?'.api_get_cidreq().'&category='.$category_id.'&action=self_reg&group_id='.$this_group['id'].'"
2420
                        onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES, $charset))."'".')) return false;">'.get_lang('GroupSelfRegInf').'</a>';
2421
                } elseif (self::is_self_unregistration_allowed($user_id, $this_group)) {
2422
                    $row[] = '<a class = "btn btn-default"
2423
                        href="group.php?'.api_get_cidreq().'&category='.$category_id.'&action=self_unreg&group_id='.$this_group['id'].'"
2424
                        onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES, $charset))."'".')) return false;">'.get_lang('GroupSelfUnRegInf').'</a>';
2425
                } else {
2426
                    $row[] = '-';
2427
                }
2428
            }
2429
2430
            // Edit-links
2431
            if (api_is_allowed_to_edit(false, true) &&
2432
                !(api_is_session_general_coach() && intval($this_group['session_id']) != $session_id)
2433
            ) {
2434
                $edit_actions = '<a href="'.$url.'settings.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'" title="'.get_lang('Edit').'">'.
2435
                    Display::return_icon('edit.png', get_lang('EditGroup'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2436
2437
                if ($this_group['status'] == 1) {
2438
                    $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').'">'.
2439
                        Display::return_icon('visible.png', get_lang('Hide'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2440
                } else {
2441
                    $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').'">'.
2442
                        Display::return_icon('invisible.png', get_lang('Show'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2443
                }
2444
2445
                $edit_actions .= '<a href="'.$url.'member_settings.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'" title="'.get_lang('GroupMembers').'">'.
2446
                    Display::return_icon('user.png', get_lang('GroupMembers'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2447
2448
                $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').'">'.
2449
                    Display::return_icon('export_excel.png', get_lang('Export'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2450
2451
                if ($surveyGroupExists) {
2452
                    $edit_actions .= Display::url(
2453
                            Display::return_icon('survey.png', get_lang('ExportSurveyResults'), '', ICON_SIZE_SMALL),
2454
                            $url.'group_overview.php?action=export_surveys&'.api_get_cidreq(true, false).'&id='.$this_group['id']
2455
                        ).'&nbsp;';
2456
                }
2457
                $edit_actions .= '<a href="'.api_get_self().'?'.api_get_cidreq(true, false).'&category='.$category_id.'&action=fill_one&id='.$this_group['id'].'"
2458
                    onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;" title="'.get_lang('FillGroup').'">'.
2459
                    Display::return_icon('fill.png', get_lang('FillGroup'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2460
2461
                $edit_actions .= '<a href="'.api_get_self().'?'.api_get_cidreq(true, false).'&category='.$category_id.'&action=delete_one&id='.$this_group['id'].'"
2462
                    onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;" title="'.get_lang('Delete').'">'.
2463
                    Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2464
2465
                $row[] = $edit_actions;
2466
            }
2467
            if (!empty($this_group['nbMember'])) {
2468
                $totalRegistered = $totalRegistered + $this_group['nbMember'];
2469
            }
2470
            $group_data[] = $row;
2471
        }
2472
2473
        // If no groups then don't show the table (only for students)
2474
        if (!api_is_allowed_to_edit(true, false)) {
2475
            if (empty($group_data)) {
2476
                return '';
2477
            }
2478
        }
2479
2480
        $table = new SortableTableFromArrayConfig(
2481
            $group_data,
2482
            1,
2483
            20,
2484
            'group_category_'.$category_id
2485
        );
2486
        $table->set_additional_parameters(['category' => $category_id]);
2487
        $column = 0;
2488
        if (api_is_allowed_to_edit(false, true) && count($group_list) > 1) {
2489
            $table->set_header($column++, '', false);
2490
        }
2491
        $table->set_header($column++, get_lang('Groups'));
2492
        $table->set_header($column++, get_lang('GroupTutor'));
2493
        $table->set_header($column++, get_lang('Registered'), false);
2494
2495
        if (!api_is_allowed_to_edit(false, true)) {
2496
            // If self-registration allowed
2497
            $table->set_header($column++, get_lang('GroupSelfRegistration'), false);
2498
        }
2499
2500
        if (api_is_allowed_to_edit(false, true)) {
2501
            // Only for course administrator
2502
            $table->set_header($column++, get_lang('Modify'), false);
2503
            $form_actions = [];
2504
            $form_actions['fill_selected'] = get_lang('FillGroup');
2505
            $form_actions['empty_selected'] = get_lang('EmptyGroup');
2506
            $form_actions['delete_selected'] = get_lang('Delete');
2507
            if (count($group_list) > 1) {
2508
                $table->set_form_actions($form_actions, 'group');
2509
            }
2510
        }
2511
2512
        return $table->return_table();
2513
    }
2514
2515
    /**
2516
     * @param array $groupData
2517
     * @param bool  $deleteNotInArray
2518
     *
2519
     * @return array
2520
     */
2521
    public static function importCategoriesAndGroupsFromArray(
2522
        $groupData,
2523
        $deleteNotInArray = false
2524
    ) {
2525
        $result = [];
2526
        $elementsFound = [
2527
            'categories' => [],
2528
            'groups' => [],
2529
        ];
2530
2531
        $courseCode = api_get_course_id();
2532
        $sessionId = api_get_session_id();
2533
        $groupCategories = self::get_categories();
2534
2535
        if (empty($groupCategories)) {
2536
            $result['error'][] = get_lang('CreateACategory');
2537
2538
            return $result;
2539
        }
2540
2541
        foreach ($groupData as $data) {
2542
            $isCategory = empty($data['group']) ? true : false;
2543
            if ($isCategory) {
2544
                $categoryInfo = self::getCategoryByTitle($data['category']);
2545
                $categoryId = $categoryInfo['id'];
2546
2547
                if (!empty($categoryInfo)) {
2548
                    // Update
2549
                    self::update_category(
2550
                        $categoryId,
2551
                        $data['category'],
2552
                        $data['description'],
2553
                        $data['doc_state'],
2554
                        $data['work_state'],
2555
                        $data['calendar_state'],
2556
                        $data['announcements_state'],
2557
                        $data['forum_state'],
2558
                        $data['wiki_state'],
2559
                        $data['chat_state'],
2560
                        $data['self_reg_allowed'],
2561
                        $data['self_unreg_allowed'],
2562
                        $data['max_student'],
2563
                        $data['groups_per_user'],
2564
                        isset($data['document_access']) ? $data['document_access'] : null
2565
                    );
2566
                    $data['category_id'] = $categoryId;
2567
                    $result['updated']['category'][] = $data;
2568
                } else {
2569
                    // Add
2570
                    $categoryId = self::create_category(
2571
                        $data['category'],
2572
                        $data['description'],
2573
                        $data['doc_state'],
2574
                        $data['work_state'],
2575
                        $data['calendar_state'],
2576
                        $data['announcements_state'],
2577
                        $data['forum_state'],
2578
                        $data['wiki_state'],
2579
                        $data['chat_state'],
2580
                        $data['self_reg_allowed'],
2581
                        $data['self_unreg_allowed'],
2582
                        $data['max_student'],
2583
                        $data['groups_per_user']
2584
                    );
2585
2586
                    if ($categoryId) {
2587
                        $data['category_id'] = $categoryId;
2588
                        $result['added']['category'][] = $data;
2589
                    }
2590
                }
2591
                $elementsFound['categories'][] = $categoryId;
2592
            } else {
2593
                $groupInfo = self::getGroupByName($data['group']);
2594
                $categoryInfo = [];
2595
                if (isset($data['category'])) {
2596
                    $categoryInfo = self::getCategoryByTitle($data['category']);
2597
                }
2598
                $categoryId = null;
2599
                if (!empty($categoryInfo)) {
2600
                    $categoryId = $categoryInfo['id'];
2601
                } else {
2602
                    if (!empty($groupCategories) && isset($groupCategories[0])) {
2603
                        $defaultGroupCategory = $groupCategories[0];
2604
                        $categoryId = $defaultGroupCategory['id'];
2605
                    }
2606
                }
2607
2608
                if (empty($groupInfo)) {
2609
                    // Add
2610
                    $groupId = self::create_group(
2611
                        $data['group'],
2612
                        $categoryId,
2613
                        null,
2614
                        $data['max_student']
2615
                    );
2616
2617
                    if ($groupId) {
2618
                        self::set_group_properties(
2619
                            $groupId,
2620
                            $data['group'],
2621
                            $data['description'],
2622
                            $data['max_student'],
2623
                            $data['doc_state'],
2624
                            $data['work_state'],
2625
                            $data['calendar_state'],
2626
                            $data['announcements_state'],
2627
                            $data['forum_state'],
2628
                            $data['wiki_state'],
2629
                            $data['chat_state'],
2630
                            $data['self_reg_allowed'],
2631
                            $data['self_unreg_allowed'],
2632
                            $categoryId
2633
                        );
2634
                        $data['group_id'] = $groupId;
2635
                        $result['added']['group'][] = $data;
2636
                    }
2637
                    $groupInfo = self::get_group_properties($groupId, true);
2638
                } else {
2639
                    // Update
2640
                    $groupId = $groupInfo['id'];
2641
                    self::set_group_properties(
2642
                        $groupId,
2643
                        $data['group'],
2644
                        $data['description'],
2645
                        $data['max_student'],
2646
                        $data['doc_state'],
2647
                        $data['work_state'],
2648
                        $data['calendar_state'],
2649
                        $data['announcements_state'],
2650
                        $data['forum_state'],
2651
                        $data['wiki_state'],
2652
                        $data['chat_state'],
2653
                        $data['self_reg_allowed'],
2654
                        $data['self_unreg_allowed'],
2655
                        $categoryId
2656
                    );
2657
2658
                    $data['group_id'] = $groupId;
2659
                    $result['updated']['group'][] = $data;
2660
                    $groupInfo = self::get_group_properties($groupId);
2661
                }
2662
2663
                $students = isset($data['students']) ? explode(',', $data['students']) : [];
2664
                if (!empty($students)) {
2665
                    $studentUserIdList = [];
2666
                    foreach ($students as $student) {
2667
                        $userInfo = api_get_user_info_from_username($student);
2668
2669
                        if (!$userInfo) {
2670
                            continue;
2671
                        }
2672
2673
                        if (!CourseManager::is_user_subscribed_in_course(
2674
                                $userInfo['user_id'],
2675
                                $courseCode,
2676
                                !empty($sessionId),
2677
                                $sessionId
2678
                            )
2679
                        ) {
2680
                            Display::addFlash(
2681
                                Display::return_message(
2682
                                    sprintf(
2683
                                        get_lang('StudentXIsNotSubscribedToCourse'),
2684
                                        $userInfo['complete_name']
2685
                                    ),
2686
                                    'warning'
2687
                                )
2688
                            );
2689
                            continue;
2690
                        }
2691
2692
                        $studentUserIdList[] = $userInfo['user_id'];
2693
                    }
2694
                    self::subscribe_users($studentUserIdList, $groupInfo);
2695
                }
2696
2697
                $tutors = isset($data['tutors']) ? explode(',', $data['tutors']) : [];
2698
                if (!empty($tutors)) {
2699
                    $tutorIdList = [];
2700
                    foreach ($tutors as $tutor) {
2701
                        $userInfo = api_get_user_info_from_username($tutor);
2702
2703
                        if (!$userInfo) {
2704
                            continue;
2705
                        }
2706
2707
                        if (!CourseManager::is_user_subscribed_in_course(
2708
                                $userInfo['user_id'],
2709
                                $courseCode,
2710
                                !empty($sessionId),
2711
                                $sessionId
2712
                            )
2713
                        ) {
2714
                            Display::addFlash(
2715
                                Display::return_message(
2716
                                    sprintf(get_lang('TutorXIsNotSubscribedToCourse'), $userInfo['complete_name']),
2717
                                    'warning'
2718
                                )
2719
                            );
2720
2721
                            continue;
2722
                        }
2723
2724
                        $tutorIdList[] = $userInfo['user_id'];
2725
                    }
2726
                    self::subscribe_tutors($tutorIdList, $groupInfo);
2727
                }
2728
2729
                $elementsFound['groups'][] = $groupId;
2730
            }
2731
        }
2732
2733
        if ($deleteNotInArray) {
2734
            // Check categories
2735
            $categories = self::get_categories();
2736
            foreach ($categories as $category) {
2737
                if (!in_array($category['id'], $elementsFound['categories'])) {
2738
                    self::delete_category($category['id']);
2739
                    $category['category'] = $category['title'];
2740
                    $result['deleted']['category'][] = $category;
2741
                }
2742
            }
2743
2744
            $groups = self::get_groups();
2745
            foreach ($groups as $group) {
2746
                if (!in_array($group['iid'], $elementsFound['groups'])) {
2747
                    self::deleteGroup($group);
2748
                    $group['group'] = $group['name'];
2749
                    $result['deleted']['group'][] = $group;
2750
                }
2751
            }
2752
        }
2753
2754
        return $result;
2755
    }
2756
2757
    /**
2758
     * Export all categories/group from a course to an array.
2759
     * This function works only in a context of a course.
2760
     *
2761
     * @param int  $groupId
2762
     * @param bool $loadUsers
2763
     *
2764
     * @return array
2765
     */
2766
    public static function exportCategoriesAndGroupsToArray($groupId = null, $loadUsers = false)
2767
    {
2768
        $data = [];
2769
        $data[] = [
2770
            'category',
2771
            'group',
2772
            'description',
2773
            'announcements_state',
2774
            'calendar_state',
2775
            'chat_state',
2776
            'doc_state',
2777
            'forum_state',
2778
            'work_state',
2779
            'wiki_state',
2780
            'max_student',
2781
            'self_reg_allowed',
2782
            'self_unreg_allowed',
2783
            'groups_per_user',
2784
        ];
2785
2786
        $count = 1;
2787
2788
        if ($loadUsers) {
2789
            $data[0][] = 'students';
2790
            $data[0][] = 'tutors';
2791
        }
2792
2793
        if (false == $loadUsers) {
2794
            $categories = self::get_categories();
2795
2796
            foreach ($categories as $categoryInfo) {
2797
                $data[$count] = [
2798
                    $categoryInfo['title'],
2799
                    null,
2800
                    $categoryInfo['description'],
2801
                    $categoryInfo['announcements_state'],
2802
                    $categoryInfo['calendar_state'],
2803
                    $categoryInfo['chat_state'],
2804
                    $categoryInfo['doc_state'],
2805
                    $categoryInfo['forum_state'],
2806
                    $categoryInfo['work_state'],
2807
                    $categoryInfo['wiki_state'],
2808
                    $categoryInfo['max_student'],
2809
                    $categoryInfo['self_reg_allowed'],
2810
                    $categoryInfo['self_unreg_allowed'],
2811
                    $categoryInfo['groups_per_user'],
2812
                ];
2813
                $count++;
2814
            }
2815
        }
2816
2817
        $groups = self::get_group_list();
2818
2819
        foreach ($groups as $groupInfo) {
2820
            $categoryTitle = null;
2821
            $categoryInfo = self::get_category($groupInfo['category_id']);
2822
            $groupSettings = self::get_group_properties($groupInfo['id']);
2823
            if (!empty($categoryInfo)) {
2824
                $categoryTitle = $categoryInfo['title'];
2825
            }
2826
2827
            $users = self::getStudents($groupInfo['iid']);
2828
            $userList = [];
2829
            foreach ($users as $user) {
2830
                $user = api_get_user_info($user['user_id']);
2831
                $userList[] = $user['username'];
2832
            }
2833
2834
            $tutors = self::getTutors($groupInfo);
2835
            $tutorList = [];
2836
            foreach ($tutors as $user) {
2837
                $user = api_get_user_info($user['user_id']);
2838
                $tutorList[] = $user['username'];
2839
            }
2840
2841
            $userListToString = null;
2842
            if (!empty($userList)) {
2843
                $userListToString = implode(',', $userList);
2844
            }
2845
2846
            $tutorListToString = null;
2847
            if (!empty($tutorList)) {
2848
                $tutorListToString = implode(',', $tutorList);
2849
            }
2850
2851
            $data[$count] = [
2852
                $categoryTitle,
2853
                $groupSettings['name'],
2854
                $groupSettings['description'],
2855
                $groupSettings['announcements_state'],
2856
                $groupSettings['calendar_state'],
2857
                $groupSettings['chat_state'],
2858
                $groupSettings['doc_state'],
2859
                $groupSettings['forum_state'],
2860
                $groupSettings['work_state'],
2861
                $groupSettings['wiki_state'],
2862
                $groupSettings['maximum_number_of_students'],
2863
                $groupSettings['self_registration_allowed'],
2864
                $groupSettings['self_unregistration_allowed'],
2865
                null,
2866
            ];
2867
2868
            if ($loadUsers) {
2869
                $data[$count][] = $userListToString;
2870
                $data[$count][] = $tutorListToString;
2871
            }
2872
2873
            if (!empty($groupId)) {
2874
                if ($groupId == $groupInfo['id']) {
2875
                    break;
2876
                }
2877
            }
2878
            $count++;
2879
        }
2880
2881
        return $data;
2882
    }
2883
2884
    /**
2885
     * @param string $default
2886
     */
2887
    public static function getSettingBar($default)
2888
    {
2889
        $activeSettings = null;
2890
        $activeTutor = null;
2891
        $activeMember = null;
2892
2893
        switch ($default) {
2894
            case 'settings':
2895
                $activeSettings = 'active';
2896
                break;
2897
            case 'tutor':
2898
                $activeTutor = 'active';
2899
                break;
2900
            case 'member':
2901
                $activeMember = 'active';
2902
                break;
2903
        }
2904
2905
        $url = api_get_path(WEB_CODE_PATH).'group/%s?'.api_get_cidreq();
2906
2907
        echo '
2908
            <ul class="toolbar-groups nav nav-tabs">
2909
                <li class="'.$activeSettings.'">
2910
                    <a id="group_settings_tab" href="'.sprintf($url, 'settings.php').'">
2911
                    '.Display::return_icon('settings.png').' '.get_lang('Settings').'
2912
                    </a>
2913
                </li>
2914
                <li class="'.$activeMember.'">
2915
                    <a id="group_members_tab" href="'.sprintf($url, 'member_settings.php').'">
2916
                    '.Display::return_icon('user.png').' '.get_lang('GroupMembers').'</a>
2917
                </li>
2918
                <li class="'.$activeTutor.'">
2919
                    <a id="group_tutors_tab" href="'.sprintf($url, 'tutor_settings.php').'">
2920
                    '.Display::return_icon('teacher.png').' '.get_lang('GroupTutors').'
2921
                    </a>
2922
                </li>
2923
            </ul>';
2924
    }
2925
2926
    public static function groupOverview($group, $url)
2927
    {
2928
        $groupId = $group['id'];
2929
        $content = '<li>';
2930
        $content .= Display::tag(
2931
            'h3',
2932
            Display::url(
2933
                Security::remove_XSS($group['name']),
2934
                $url.'&gidReq='.$groupId
2935
            )
2936
        );
2937
        $users = self::getTutors($group);
2938
        if (!empty($users)) {
2939
            $content .= '<ul>';
2940
            $content .= "<li>".Display::tag('h4', get_lang('Tutors'))."</li><ul>";
2941
            foreach ($users as $user) {
2942
                $userInfo = api_get_user_info($user['user_id']);
2943
                $content .= '<li title="'.$userInfo['username'].'">'.
2944
                    $userInfo['complete_name_with_username'].
2945
                    '</li>';
2946
            }
2947
            $content .= '</ul>';
2948
            $content .= '</ul>';
2949
        }
2950
2951
        $users = self::getStudents($group['id']);
2952
        if (!empty($users)) {
2953
            $content .= '<ul>';
2954
            $content .= "<li>".Display::tag('h4', get_lang('Students'))."</li><ul>";
2955
            foreach ($users as $user) {
2956
                $userInfo = api_get_user_info($user['user_id']);
2957
                $content .= '<li title="'.$userInfo['username'].'">'.
2958
                    $userInfo['complete_name_with_username'].
2959
                    '</li>';
2960
            }
2961
            $content .= '</ul>';
2962
            $content .= '</ul>';
2963
        }
2964
        $content .= '</li>';
2965
2966
        return $content;
2967
    }
2968
2969
    /**
2970
     * @param int    $courseId
2971
     * @param string $keyword
2972
     *
2973
     * @return string
2974
     */
2975
    public static function getOverview($courseId, $keyword = '')
2976
    {
2977
        $content = null;
2978
        $categories = self::get_categories();
2979
        $url = api_get_path(WEB_CODE_PATH).'group/group_space.php?'.api_get_cidreq(true, false);
2980
        if (!empty($categories)) {
2981
            foreach ($categories as $category) {
2982
                if ('true' === api_get_setting('allow_group_categories')) {
2983
                    $content .= '<h2>'.$category['title'].'</h2>';
2984
                }
2985
2986
                if (!empty($keyword)) {
2987
                    $groups = self::getGroupListFilterByName(
2988
                        $keyword,
2989
                        $category['id'],
2990
                        $courseId
2991
                    );
2992
                } else {
2993
                    $groups = self::get_group_list($category['id']);
2994
                }
2995
2996
                $content .= '<ul>';
2997
                if (!empty($groups)) {
2998
                    foreach ($groups as $group) {
2999
                        $content .= self::groupOverview($group, $url);
3000
                    }
3001
                }
3002
                $content .= '</ul>';
3003
            }
3004
        }
3005
3006
        // Check groups with no categories.
3007
        $groups = self::get_group_list(null, api_get_course_info(), null, api_get_session_id(), false, true);
3008
        if (!empty($groups)) {
3009
            $content .= '<h2>'.get_lang('NoCategorySelected').'</h2>';
3010
            $content .= '<ul>';
3011
            foreach ($groups as $group) {
3012
                if (!empty($group['category_id'])) {
3013
                    continue;
3014
                }
3015
                $content .= self::groupOverview($group, $url);
3016
            }
3017
            $content .= '</ul>';
3018
        }
3019
3020
        return $content;
3021
    }
3022
3023
    /**
3024
     * Returns the search form.
3025
     *
3026
     * @return string
3027
     */
3028
    public static function getSearchForm()
3029
    {
3030
        $url = api_get_path(WEB_CODE_PATH).'group/group_overview.php?'.api_get_cidreq();
3031
        $form = new FormValidator(
3032
            'search_groups',
3033
            'get',
3034
            $url,
3035
            null,
3036
            ['class' => 'form-search'],
3037
            FormValidator::LAYOUT_INLINE
3038
        );
3039
        $form->addElement('text', 'keyword');
3040
        $form->addButtonSearch();
3041
3042
        return $form->toHtml();
3043
    }
3044
3045
    /**
3046
     * @param int $groupId
3047
     * @param int $status
3048
     */
3049
    public static function setStatus($groupId, $status)
3050
    {
3051
        $groupInfo = self::get_group_properties($groupId);
3052
3053
        $courseId = api_get_course_int_id();
3054
        if (!empty($groupInfo)) {
3055
            $table = Database::get_course_table(TABLE_GROUP);
3056
            $params = [
3057
                'status' => intval($status),
3058
            ];
3059
            Database::update(
3060
                $table,
3061
                $params,
3062
                ['c_id = ? AND id = ?' => [$courseId, $groupId]]
3063
            );
3064
        }
3065
    }
3066
3067
    /**
3068
     * @param int $groupId
3069
     */
3070
    public static function setVisible($groupId)
3071
    {
3072
        self::setStatus($groupId, 1);
3073
    }
3074
3075
    /**
3076
     * @param int $groupId
3077
     */
3078
    public static function setInvisible($groupId)
3079
    {
3080
        self::setStatus($groupId, 0);
3081
    }
3082
3083
    /**
3084
     * @param int   $userId
3085
     * @param int   $courseId
3086
     * @param array $groupInfo
3087
     * @param array $documentInfoToBeCheck
3088
     * @param bool  $blockPage
3089
     *
3090
     * @return bool
3091
     */
3092
    public static function allowUploadEditDocument(
3093
        $userId,
3094
        $courseId,
3095
        $groupInfo,
3096
        $documentInfoToBeCheck = null,
3097
        $blockPage = false
3098
    ) {
3099
        // Admin and teachers can make any change no matter what
3100
        if (api_is_platform_admin() || api_is_allowed_to_edit(false, true)) {
3101
            return true;
3102
        }
3103
3104
        if (empty($groupInfo) || !isset($groupInfo['id'])) {
3105
            if ($blockPage) {
3106
                api_not_allowed(true);
3107
            }
3108
3109
            return false;
3110
        }
3111
3112
        // Tutor can also make any change
3113
        $isTutor = self::is_tutor_of_group($userId, $groupInfo, $courseId);
3114
3115
        if ($isTutor) {
3116
            return true;
3117
        }
3118
3119
        // Just in case also check if document in group is available
3120
        if ($groupInfo['doc_state'] == 0) {
3121
            if ($blockPage) {
3122
                api_not_allowed(true);
3123
            }
3124
3125
            return false;
3126
        }
3127
3128
        // Default behaviour
3129
        $documentAccess = self::DOCUMENT_MODE_SHARE;
3130
3131
        // Check category document access
3132
        /*$allowCategoryGroupDocumentAccess = api_get_configuration_value('group_category_document_access');
3133
        if ($allowCategoryGroupDocumentAccess) {
3134
            $category = GroupManager::get_category_from_group($groupInfo['iid']);
3135
            if (!empty($category) && isset($category['document_access'])) {
3136
                $documentAccess = (int) $category['document_access'];
3137
            }
3138
        }*/
3139
3140
        // Check group document access
3141
        $allow = api_get_configuration_value('group_document_access');
3142
        if ($allow) {
3143
            if (isset($groupInfo['document_access'])) {
3144
                $documentAccess = (int) $groupInfo['document_access'];
3145
            }
3146
        }
3147
3148
        // Check access for students
3149
        $result = false;
3150
        switch ($documentAccess) {
3151
            case self::DOCUMENT_MODE_SHARE:
3152
                // Default chamilo behaviour
3153
                // Student can upload his own content, cannot modify another content.
3154
                $isMember = self::is_subscribed($userId, $groupInfo);
3155
                if ($isMember) {
3156
                    // No document to check, allow access to document feature.
3157
                    if (empty($documentInfoToBeCheck)) {
3158
                        $result = true;
3159
                    } else {
3160
                        // Member can only edit his own document
3161
                        $authorId = isset($documentInfoToBeCheck['insert_user_id']) ? $documentInfoToBeCheck['insert_user_id'] : 0;
3162
                        // If "insert_user_id" is not set, check the author id from c_item_property
3163
                        if (empty($authorId) && isset($documentInfoToBeCheck['id'])) {
3164
                            $documentInfo = api_get_item_property_info(
3165
                                $courseId,
3166
                                'document',
3167
                                $documentInfoToBeCheck['id'],
3168
                                0
3169
                            );
3170
                            // Try to find this document in the session
3171
                            if (!empty($sessionId)) {
3172
                                $documentInfo = api_get_item_property_info(
3173
                                    $courseId,
3174
                                    'document',
3175
                                    $documentInfoToBeCheck['id'],
3176
                                    api_get_session_id()
3177
                                );
3178
                            }
3179
3180
                            if (!empty($documentInfo) && isset($documentInfo['insert_user_id'])) {
3181
                                $authorId = $documentInfo['insert_user_id'];
3182
                            }
3183
                        }
3184
3185
                        if ($authorId == $userId) {
3186
                            $result = true;
3187
                        }
3188
                    }
3189
                }
3190
                break;
3191
            case self::DOCUMENT_MODE_READ_ONLY:
3192
                // Student cannot upload content, cannot modify another content.
3193
                $result = false;
3194
                break;
3195
            case self::DOCUMENT_MODE_COLLABORATION:
3196
                // Student can upload content, can modify another content.
3197
                $isMember = self::is_subscribed($userId, $groupInfo);
3198
                if ($isMember) {
3199
                    $result = true;
3200
                }
3201
                break;
3202
        }
3203
3204
        if ($blockPage && $result == false) {
3205
            api_not_allowed(true);
3206
        }
3207
3208
        return $result;
3209
    }
3210
}
3211