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