Completed
Push — master ( ae5621...ef667c )
by Julito
13:23
created

GroupManager::set_group_properties()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 63
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

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

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

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