Passed
Push — master ( 44ae74...4bbff2 )
by Julito
10:31
created

GroupManager::unsubscribeAllUsers()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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