GroupManager::create_category()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 47
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 25
nc 2
nop 14
dl 0
loc 47
rs 9.52
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

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

There are several approaches to avoid long parameter lists:

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