Test Setup Failed
Push — master ( c7183e...00c715 )
by Julito
30:43
created

GroupManager::set_group_properties()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 54
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 47
nc 4
nop 14
dl 0
loc 54
rs 9.0306
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
 * @author Bart Mollet
9
 * @package chamilo.library
10
 * @todo Add $course_code parameter to all functions. So this GroupManager can
11
 * be used outside a session.
12
 */
13
class GroupManager
14
{
15
    /* VIRTUAL_COURSE_CATEGORY:
16
    in this category groups are created based on the virtual course of a course*/
17
    const VIRTUAL_COURSE_CATEGORY = 1;
18
19
    /* DEFAULT_GROUP_CATEGORY:
20
    When group categories aren't available (platform-setting),
21
    all groups are created in this 'dummy'-category*/
22
    const DEFAULT_GROUP_CATEGORY = 2;
23
24
    /**
25
     * infinite
26
     */
27
    const INFINITE = 99999;
28
    /**
29
     * No limit on the number of users in a group
30
     */
31
    const MEMBER_PER_GROUP_NO_LIMIT = 0;
32
    /**
33
     * No limit on the number of groups per user
34
     */
35
    const GROUP_PER_MEMBER_NO_LIMIT = 0;
36
    /**
37
     * The tools of a group can have 3 states
38
     * - not available
39
     * - public
40
     * - private
41
     */
42
    const TOOL_NOT_AVAILABLE = 0;
43
    const TOOL_PUBLIC = 1;
44
    const TOOL_PRIVATE = 2;
45
    /**
46
     * Constants for the available group tools
47
     */
48
    const GROUP_TOOL_FORUM = 0;
49
    const GROUP_TOOL_DOCUMENTS = 1;
50
    const GROUP_TOOL_CALENDAR = 2;
51
    const GROUP_TOOL_ANNOUNCEMENT = 3;
52
    const GROUP_TOOL_WORK = 4;
53
    const GROUP_TOOL_WIKI = 5;
54
    const GROUP_TOOL_CHAT = 6;
55
56
    /**
57
     *
58
     */
59
    public function __construct()
60
    {
61
    }
62
63
    /**
64
     * @return array
65
     */
66 View Code Duplication
    public static function get_groups($courseId = null)
67
    {
68
        $table_group = Database::get_course_table(TABLE_GROUP);
69
        $courseId = !empty($courseId) ? (int) $courseId : api_get_course_int_id();
70
71
        $sql = "SELECT * FROM $table_group WHERE c_id = $courseId  ";
72
        $result = Database::query($sql);
73
        return Database::store_result($result, 'ASSOC');
74
    }
75
76
    /**
77
     * Get list of groups for current course.
78
     * @param int $categoryId The id of the category from which the groups are
79
     * requested
80
     * @param array $course_info Default is current course
81
     * @param int $status
82
     * @param int $sessionId
83
     * @return array An array with all information about the groups.
84
     */
85
    public static function get_group_list(
86
        $categoryId = null,
87
        $course_info = [],
88
        $status = null,
89
        $sessionId = 0
90
    ) {
91
        $course_info = empty($course_info) ? api_get_course_info() : $course_info;
92
        if (empty($course_info)) {
93
            return [];
94
        }
95
        $sessionId = empty($sessionId) ? api_get_session_id() : (int) $sessionId;
96
        $course_id = $course_info['real_id'];
97
        $table_group = Database::get_course_table(TABLE_GROUP);
98
99
        $sql = "SELECT 
100
                    g.id,
101
                    g.iid,
102
                    g.name,
103
                    g.description,
104
                    g.category_id,
105
                    g.max_student maximum_number_of_members,
106
                    g.secret_directory,
107
                    g.self_registration_allowed,
108
                    g.self_unregistration_allowed,
109
                    g.session_id,
110
                    g.status
111
                FROM $table_group g
112
                WHERE 1 = 1 ";
113
114
        if (!is_null($categoryId)) {
115
            $sql .= " AND g.category_id = '".intval($categoryId)."' ";
116
            $session_condition = api_get_session_condition($sessionId);
117
            if (!empty($session_condition)) {
118
                $sql .= $session_condition;
119
            }
120
        } else {
121
            $session_condition = api_get_session_condition($sessionId, true);
122
        }
123
124
        if (!is_null($status)) {
125
            $sql .= " AND g.status = '".intval($status)."' ";
126
        }
127
128
        $sql .= " AND g.c_id = $course_id ";
129
130
        if (!empty($session_condition)) {
131
            $sql .= $session_condition;
132
        }
133
        $sql .= "ORDER BY UPPER(g.name)";
134
135
        $groupList = Database::query($sql);
136
137
        $groups = array();
138
        while ($thisGroup = Database::fetch_array($groupList)) {
139
            $thisGroup['number_of_members'] = count(self::get_subscribed_users($thisGroup));
140
            if ($thisGroup['session_id'] != 0) {
141
                $sql = 'SELECT name FROM '.Database::get_main_table(TABLE_MAIN_SESSION).'
142
                        WHERE id='.$thisGroup['session_id'];
143
                $rs_session = Database::query($sql);
144
                if (Database::num_rows($rs_session) > 0) {
145
                    $thisGroup['session_name'] = Database::result($rs_session, 0, 0);
146
                }
147
            }
148
            $groups[] = $thisGroup;
149
        }
150
151
        return $groups;
152
    }
153
154
    /**
155
     * Create a group
156
     * @param string $name The name for this group
157
     * @param int $category_id
158
     * @param int $tutor The user-id of the group's tutor
159
     * @param int $places How many people can subscribe to the new group
160
     *
161
     * @return int
162
     */
163
    public static function create_group($name, $category_id, $tutor, $places)
164
    {
165
        $_course = api_get_course_info();
166
        $session_id = api_get_session_id();
167
        $course_id  = $_course['real_id'];
168
        $currentCourseRepository = $_course['path'];
169
        $category = self::get_category($category_id);
170
        $places = intval($places);
171
172
        if ($category) {
173
            if ($places == 0) {
174
                //if the amount of users per group is not filled in, use the setting from the category
175
                $places = $category['max_student'];
176
            } else {
177
                if ($places > $category['max_student'] && $category['max_student'] != 0) {
178
                    $places = $category['max_student'];
179
                }
180
            }
181
            $docState = $category['doc_state'];
182
            $calendarState = $category['calendar_state'];
183
            $workState = $category['work_state'];
184
            $anonuncementState = $category['announcements_state'];
185
            $forumState = $category['forum_state'];
186
            $wikiState = $category['wiki_state'];
187
            $chatState = $category['chat_state'];
188
            $selfRegAllowed = $category['self_reg_allowed'];
189
            $selfUnregAllwoed = $category['self_unreg_allowed'];
190
191
        } else {
192
            $docState = self::TOOL_PRIVATE;
193
            $calendarState = self::TOOL_PRIVATE;
194
            $workState = self::TOOL_PRIVATE;
195
            $anonuncementState = self::TOOL_PRIVATE;
196
            $forumState = self::TOOL_PRIVATE;
197
            $wikiState = self::TOOL_PRIVATE;
198
            $chatState = self::TOOL_PRIVATE;
199
            $selfRegAllowed = 0;
200
            $selfUnregAllwoed = 0;
201
        }
202
203
        $table_group = Database::get_course_table(TABLE_GROUP);
204
        $sql = "INSERT INTO $table_group SET
205
                c_id = $course_id,
206
                status = 1,
207
                category_id='".Database::escape_string($category_id)."',
208
                max_student = '".$places."',
209
                doc_state = '".$docState."',
210
                calendar_state = '".$calendarState."',
211
                work_state = '".$workState."',
212
                announcements_state = '".$anonuncementState."',
213
                forum_state = '".$forumState."',
214
                wiki_state = '".$wikiState."',
215
                chat_state = '".$chatState."',
216
                self_registration_allowed = '".$selfRegAllowed."',
217
                self_unregistration_allowed = '".$selfUnregAllwoed."',
218
                session_id='".intval($session_id)."'";
219
220
        Database::query($sql);
221
        $lastId = Database::insert_id();
222
223
        if ($lastId) {
224
            $sql = "UPDATE $table_group SET id = iid WHERE iid = $lastId";
225
            Database::query($sql);
226
227
            $desired_dir_name = '/'.api_replace_dangerous_char($name).'_groupdocs';
228
            $my_path = api_get_path(SYS_COURSE_PATH).$currentCourseRepository.'/document';
229
230
            $newFolderData = create_unexisting_directory(
231
                $_course,
232
                api_get_user_id(),
233
                $session_id,
234
                $lastId,
235
                null,
236
                $my_path,
237
                $desired_dir_name,
238
                null,
239
                1
240
            );
241
242
            $unique_name = $newFolderData['path'];
243
244
            /* Stores the directory path into the group table */
245
            $sql = "UPDATE $table_group SET
246
                        name = '".Database::escape_string($name)."',
247
                        secret_directory = '".$unique_name."'
248
                    WHERE c_id = $course_id AND id ='".$lastId."'";
249
250
            Database::query($sql);
251
252
            // create a forum if needed
253
            if ($forumState >= 0) {
254
                require_once api_get_path(SYS_CODE_PATH).'forum/forumconfig.inc.php';
255
                require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
256
257
                $forum_categories = get_forum_categories();
258
                if (empty($forum_categories)) {
259
                    $categoryParam = array(
260
                        'forum_category_title' => get_lang('GroupForums'),
261
                    );
262
                    store_forumcategory($categoryParam);
263
264
                    $forum_categories = get_forum_categories();
265
                }
266
267
                $counter = 0;
268
                foreach ($forum_categories as $key => $value) {
269
                    if ($counter == 0) {
270
                        $forum_category_id = $key;
271
                    }
272
                    $counter++;
273
                }
274
                // A sanity check.
275
                if (empty($forum_category_id)) {
276
                    $forum_category_id = 0;
277
                }
278
279
                $values = array();
280
                $values['forum_title'] = $name;
281
                $values['group_id'] = $lastId;
282
                $values['forum_category'] = $forum_category_id;
283
                $values['allow_anonymous_group']['allow_anonymous'] = 0;
284
                $values['students_can_edit_group']['students_can_edit'] = 0;
285
                $values['approval_direct_group']['approval_direct'] = 0;
286
                $values['allow_attachments_group']['allow_attachments'] = 1;
287
                $values['allow_new_threads_group']['allow_new_threads'] = 1;
288
                $values['default_view_type_group']['default_view_type'] = api_get_setting('default_forum_view');
289
                $values['group_forum'] = $lastId;
290
                if ($forumState == '1') {
291
                    $values['public_private_group_forum_group']['public_private_group_forum'] = 'public';
292
                } elseif ($forumState == '2') {
293
                    $values['public_private_group_forum_group']['public_private_group_forum'] = 'private';
294
                } elseif ($forumState == '0') {
295
                    $values['public_private_group_forum_group']['public_private_group_forum'] = 'unavailable';
296
                }
297
                store_forum($values);
298
            }
299
        }
300
301
        return $lastId;
302
    }
303
304
    /**
305
     * Create subgroups.
306
     * This function creates new groups based on an existing group. It will
307
     * create the specified number of groups and fill those groups with users
308
     * from the base group
309
     * @param int $group_id The group from which subgroups have to be created.
310
     * @param int $number_of_groups The number of groups that have to be created
311
     */
312
    public static function create_subgroups($group_id, $number_of_groups)
313
    {
314
        $course_id = api_get_course_int_id();
315
        $table_group = Database::get_course_table(TABLE_GROUP);
316
        $category_id = self::create_category(
317
            get_lang('Subgroups'),
318
            '',
319
            self::TOOL_PRIVATE,
320
            self::TOOL_PRIVATE,
321
            0,
322
            0,
323
            1,
324
            1
325
        );
326
        $users = self::get_users($group_id);
327
        $group_ids = array();
328
329
        for ($group_nr = 1; $group_nr <= $number_of_groups; $group_nr++) {
330
            $group_ids[] = self::create_group(
331
                get_lang('Subgroup').' '.$group_nr,
332
                $category_id,
333
                0,
334
                0
335
            );
336
        }
337
338
        $members = array();
339
        foreach ($users as $index => $user_id) {
340
            $groupId = $group_ids[$index % $number_of_groups];
341
            $groupInfo = self::get_group_properties($groupId);
342
            self::subscribe_users(
343
                $user_id,
344
                $groupInfo
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by self::get_group_properties($groupId) on line 341 can also be of type null; however, GroupManager::subscribe_users() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
345
            );
346
            $members[$group_ids[$groupId]]++;
347
        }
348
349
        foreach ($members as $group_id => $places) {
350
            $sql = "UPDATE $table_group SET max_student = $places
351
                    WHERE c_id = $course_id  AND id = $group_id";
352
            Database::query($sql);
353
        }
354
    }
355
356
    /**
357
     * Create a group for every class subscribed to the current course
358
     * @param int $category_id The category in which the groups should be created
359
     * @return array
360
     */
361
    public static function create_class_groups($category_id)
362
    {
363
        $options['where'] = array(" usergroup.course_id = ? " => api_get_course_int_id());
364
        $obj = new UserGroup();
365
        $classes = $obj->getUserGroupInCourse($options);
366
        $group_ids = array();
367
        foreach ($classes as $class) {
368
            $users_ids = $obj->get_users_by_usergroup($class['id']);
369
            $group_id = self::create_group(
370
                $class['name'],
371
                $category_id,
372
                0,
373
                count($users_ids)
374
            );
375
            $groupInfo = self::get_group_properties($group_id);
376
            self::subscribe_users($users_ids, $groupInfo);
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by self::get_group_properties($group_id) on line 375 can also be of type null; however, GroupManager::subscribe_users() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
377
            $group_ids[] = $group_id;
378
        }
379
        return $group_ids;
380
    }
381
382
    /**
383
     * Deletes groups and their data.
384
     * @author Christophe Gesche <[email protected]>
385
     * @author Hugues Peeters <[email protected]>
386
     * @author Bart Mollet
387
     * @param  array  $groupInfo iid
388
     * @param string $course_code Default is current course
389
     * @return integer              - number of groups deleted.
390
     */
391
    public static function delete_groups($groupInfo, $course_code = null)
392
    {
393
        $course_info = api_get_course_info($course_code);
394
        $course_id = $course_info['real_id'];
395
396
        // Database table definitions
397
        $group_table = Database::get_course_table(TABLE_GROUP);
398
        $forum_table = Database::get_course_table(TABLE_FORUM);
399
        $groupInfo = self::get_group_properties($groupInfo['iid'], true);
400
        if ($groupInfo) {
401
            $groupIid = $groupInfo['iid'];
402
            $groupId = $groupInfo['id'];
403
            $directory = $groupInfo['secret_directory'];
404
            // Unsubscribe all users
405
            self::unsubscribe_all_users($groupInfo);
406
            self::unsubscribe_all_tutors($groupInfo);
407
            // move group-documents to garbage
408
            $source_directory = api_get_path(SYS_COURSE_PATH).$course_info['path']."/document".$directory;
409
            // File to renamed
410
            $destination_dir = api_get_path(SYS_COURSE_PATH).$course_info['path']."/document".$directory.'_DELETED_'.$groupInfo['id'];
411
412
            if (!empty($directory)) {
413
                //Deleting from document tool
414
                DocumentManager::delete_document(
415
                    $course_info,
416
                    $directory,
417
                    $source_directory
418
                );
419
420 View Code Duplication
                if (file_exists($source_directory)) {
421
                    if (api_get_setting('permanently_remove_deleted_files') === 'true') {
422
                        // Delete
423
                        my_delete($source_directory);
424
                    } else {
425
                        // Rename
426
                        rename($source_directory, $destination_dir);
427
                    }
428
                }
429
            }
430
431
            $sql = "DELETE FROM $forum_table
432
                    WHERE c_id = $course_id AND forum_of_group = $groupId ";
433
            Database::query($sql);
434
435
            // Delete item properties of this group.
436
            // to_group_id is related to c_group_info.iid
437
            $itemPropertyTable = Database::get_course_table(TABLE_ITEM_PROPERTY);
438
            $sql = "DELETE FROM $itemPropertyTable
439
                    WHERE c_id = $course_id AND to_group_id = $groupIid ";
440
            Database::query($sql);
441
442
            // delete the groups
443
            $sql = "DELETE FROM $group_table
444
                    WHERE c_id = $course_id AND iid = $groupIid ";
445
            Database::query($sql);
446
        }
447
448
        return true;
449
    }
450
451
    /**
452
     * Get group properties
453
     * @param int $group_id The group from which properties are requested.
454
     * @param bool $useIid
455
     * @return array All properties. Array-keys are:
456
     * name, tutor_id, description, maximum_number_of_students,
457
     * directory and visibility of tools
458
     */
459
    public static function get_group_properties($group_id, $useIid = false)
460
    {
461
        $course_id = api_get_course_int_id();
462
        if (empty($group_id) || !is_integer(intval($group_id))) {
463
            return null;
464
        }
465
466
        $table_group = Database::get_course_table(TABLE_GROUP);
467
        $sql = "SELECT * FROM $table_group
468
                WHERE c_id = $course_id AND id = ".intval($group_id);
469
470
        if ($useIid) {
471
            $sql = "SELECT * FROM $table_group
472
                    WHERE c_id = $course_id AND iid = ".intval($group_id);
473
        }
474
        $db_result = Database::query($sql);
475
        $db_object = Database::fetch_object($db_result);
476
477
        $result = array();
478
        if ($db_object) {
479
            $result['id'] = $db_object->id;
480
            $result['iid'] = $db_object->iid;
481
            $result['name'] = $db_object->name;
482
            $result['status'] = $db_object->status;
483
            $result['description'] = $db_object->description;
484
            $result['maximum_number_of_students'] = $db_object->max_student;
485
            $result['max_student'] = $db_object->max_student;
486
            $result['doc_state'] = $db_object->doc_state;
487
            $result['work_state'] = $db_object->work_state;
488
            $result['calendar_state'] = $db_object->calendar_state;
489
            $result['announcements_state'] = $db_object->announcements_state;
490
            $result['forum_state'] = $db_object->forum_state;
491
            $result['wiki_state'] = $db_object->wiki_state;
492
            $result['chat_state'] = $db_object->chat_state;
493
            $result['directory'] = $db_object->secret_directory;
494
            $result['self_registration_allowed'] = $db_object->self_registration_allowed;
495
            $result['self_unregistration_allowed'] = $db_object->self_unregistration_allowed;
496
            $result['count_users'] = count(
497
                self::get_subscribed_users($result)
498
            );
499
            $result['count_tutor'] = count(
500
                self::get_subscribed_tutors($result)
501
            );
502
            $result['count_all'] = $result['count_users'] + $result['count_tutor'];
503
        }
504
505
        return $result;
506
    }
507
508
    /**
509
     * @param string $name
510
     * @param string $courseCode
511
     * @return array
512
     */
513 View Code Duplication
    public static function getGroupByName($name, $courseCode = null)
514
    {
515
        $name = trim($name);
516
517
        if (empty($name)) {
518
            return array();
519
        }
520
521
        $course_info = api_get_course_info($courseCode);
522
        $course_id = $course_info['real_id'];
523
        $name = Database::escape_string($name);
524
        $table_group = Database::get_course_table(TABLE_GROUP);
525
        $sql = "SELECT * FROM $table_group
526
                WHERE c_id = $course_id AND name = '$name'
527
                LIMIT 1";
528
        $res = Database::query($sql);
529
        $group = array();
530
        if (Database::num_rows($res)) {
531
            $group = Database::fetch_array($res, 'ASSOC');
532
        }
533
534
        return $group;
535
    }
536
537
    /**
538
     * @param int $courseId
539
     * @param int $categoryId
540
     * @param string $name
541
     * @return array
542
     */
543 View Code Duplication
    public static function getGroupListFilterByName($name, $categoryId, $courseId)
544
    {
545
        $name = trim($name);
546
        if (empty($name)) {
547
            return array();
548
        }
549
        $name = Database::escape_string($name);
550
        $courseId = intval($courseId);
551
        $table_group = Database::get_course_table(TABLE_GROUP);
552
        $sql = "SELECT * FROM $table_group
553
                WHERE c_id = $courseId AND name LIKE '%$name%'";
554
555
        if (!empty($categoryId)) {
556
            $categoryId = intval($categoryId);
557
            $sql .= " AND category_id = $categoryId";
558
        }
559
        $sql .= " ORDER BY name";
560
        $result = Database::query($sql);
561
562
        return Database::store_result($result, 'ASSOC');
563
    }
564
565
    /**
566
     * Set group properties
567
     * Changes the group's properties.
568
     * @param int       Group Id
569
     * @param string    Group name
570
     * @param string    Group description
571
     * @param int       Max number of students in group
572
     * @param int       Document tool's visibility (0=none,1=private,2=public)
573
     * @param int       Work tool's visibility (0=none,1=private,2=public)
574
     * @param int       Calendar tool's visibility (0=none,1=private,2=public)
575
     * @param int       Announcement tool's visibility (0=none,1=private,2=public)
576
     * @param int       Forum tool's visibility (0=none,1=private,2=public)
577
     * @param int       Wiki tool's visibility (0=none,1=private,2=public)
578
     * @param int       Chat tool's visibility (0=none,1=private,2=public)
579
     * @param bool Whether self registration is allowed or not
580
     * @param bool Whether self unregistration is allowed or not
581
     * @param int $categoryId
582
     * @return bool TRUE if properties are successfully changed, false otherwise
583
     */
584
    public static function set_group_properties(
585
        $group_id,
586
        $name,
587
        $description,
588
        $maximum_number_of_students,
589
        $doc_state,
590
        $work_state,
591
        $calendar_state,
592
        $announcements_state,
593
        $forum_state,
594
        $wiki_state,
595
        $chat_state,
596
        $self_registration_allowed,
597
        $self_unregistration_allowed,
598
        $categoryId = null
599
    ) {
600
        $table_group = Database::get_course_table(TABLE_GROUP);
601
        $table_forum = Database::get_course_table(TABLE_FORUM);
602
        $categoryId = intval($categoryId);
603
        $group_id = intval($group_id);
604
        $course_id = api_get_course_int_id();
605
606
        $sql = "UPDATE ".$table_group." SET
607
                    name='".Database::escape_string(trim($name))."',
608
                    doc_state = '".Database::escape_string($doc_state)."',
609
                    work_state = '".Database::escape_string($work_state)."',
610
                    calendar_state = '".Database::escape_string($calendar_state)."',
611
                    announcements_state = '".Database::escape_string($announcements_state)."',
612
                    forum_state = '".Database::escape_string($forum_state)."',
613
                    wiki_state = '".Database::escape_string($wiki_state)."',
614
                    chat_state = '".Database::escape_string($chat_state)."',
615
                    description ='".Database::escape_string(trim($description))."',
616
                    max_student = '".Database::escape_string($maximum_number_of_students)."',
617
                    self_registration_allowed = '".Database::escape_string($self_registration_allowed)."',
618
                    self_unregistration_allowed = '".Database::escape_string($self_unregistration_allowed)."',
619
                    category_id = ".intval($categoryId)."
620
                WHERE c_id = $course_id AND id=".$group_id;
621
        $result = Database::query($sql);
622
623
        /* Here we are updating a field in the table forum_forum that perhaps
624
        duplicates the table group_info.forum_state cvargas*/
625
        $forum_state = (int) $forum_state;
626
        $sql2 = "UPDATE ".$table_forum." SET ";
627
        if ($forum_state === 1) {
628
            $sql2 .= " forum_group_public_private='public' ";
629
        } elseif ($forum_state === 2) {
630
            $sql2 .= " forum_group_public_private='private' ";
631
        } elseif ($forum_state === 0) {
632
            $sql2 .= " forum_group_public_private='unavailable' ";
633
        }
634
        $sql2 .= " WHERE c_id = $course_id AND forum_of_group=".$group_id;
635
        Database::query($sql2);
636
        return $result;
637
    }
638
639
    /**
640
     * Get the total number of groups for the current course.
641
     * @return int The number of groups for the current course.
642
     */
643 View Code Duplication
    public static function get_number_of_groups()
644
    {
645
        $course_id = api_get_course_int_id();
646
        $table_group = Database::get_course_table(TABLE_GROUP);
647
        $sql = "SELECT COUNT(id) AS number_of_groups
648
                FROM $table_group
649
                WHERE c_id = $course_id ";
650
        $res = Database::query($sql);
651
        $obj = Database::fetch_object($res);
652
653
        return $obj->number_of_groups;
654
    }
655
656
    /**
657
     * Get all categories
658
     * @param string $course_code The course (default = current course)
659
     * @return array
660
     */
661 View Code Duplication
    public static function get_categories($course_code = null)
662
    {
663
        $course_info = api_get_course_info($course_code);
664
        $course_id = $course_info['real_id'];
665
        $table_group_cat = Database::get_course_table(TABLE_GROUP_CATEGORY);
666
        $sql = "SELECT * FROM $table_group_cat
667
                WHERE c_id = $course_id
668
                ORDER BY display_order";
669
        $res = Database::query($sql);
670
        $cats = array();
671
        while ($cat = Database::fetch_array($res)) {
672
            $cats[] = $cat;
673
        }
674
        return $cats;
675
    }
676
677
    /**
678
     * Get a group category
679
     * @param int $id The category id
680
     * @param string $course_code The course (default = current course)
681
     * @return array
682
     */
683
    public static function get_category($id, $course_code = null)
684
    {
685
        if (empty($id)) {
686
            return array();
687
        }
688
689
        $course_info = api_get_course_info($course_code);
690
        $course_id = $course_info['real_id'];
691
        $id = intval($id);
692
        $table_group_cat = Database::get_course_table(TABLE_GROUP_CATEGORY);
693
        $sql = "SELECT * FROM $table_group_cat
694
                WHERE c_id = $course_id AND id = $id
695
                LIMIT 1";
696
        $res = Database::query($sql);
697
698
        return Database::fetch_array($res);
699
    }
700
701
    /**
702
     * Get a group category
703
     * @param string $title
704
     * @param string $course_code The course (default = current course)
705
     * @return array
706
     */
707 View Code Duplication
    public static function getCategoryByTitle($title, $course_code = null)
708
    {
709
        $title = trim($title);
710
711
        if (empty($title)) {
712
            return array();
713
        }
714
715
        $course_info = api_get_course_info($course_code);
716
        $course_id = $course_info['real_id'];
717
        $title = Database::escape_string($title);
718
        $table_group_cat = Database::get_course_table(TABLE_GROUP_CATEGORY);
719
        $sql = "SELECT * FROM $table_group_cat
720
                WHERE c_id = $course_id AND title = '$title'
721
                LIMIT 1";
722
        $res = Database::query($sql);
723
        $category = array();
724
        if (Database::num_rows($res)) {
725
            $category = Database::fetch_array($res, 'ASSOC');
726
        }
727
        return $category;
728
    }
729
730
    /**
731
     * Get the unique category of a given group
732
     * @param int $group_id The iid of the group
733
     * @param string $course_code The course in which the group is (default =
734
     * current course)
735
     * @return array The category
736
     */
737 View Code Duplication
    public static function get_category_from_group($group_id, $course_code = '')
738
    {
739
        $table_group = Database::get_course_table(TABLE_GROUP);
740
        $table_group_cat = Database::get_course_table(TABLE_GROUP_CATEGORY);
741
742
        $group_id = intval($group_id);
743
744
        if (empty($group_id)) {
745
            return array();
746
        }
747
748
        $course_info = api_get_course_info($course_code);
749
750
        if (empty($course_info)) {
751
            return false;
752
        }
753
754
        $course_id = $course_info['real_id'];
755
        $sql = "SELECT gc.* FROM $table_group_cat gc, $table_group g
756
                WHERE
757
                    gc.c_id = $course_id AND
758
                    g.c_id = $course_id AND
759
                    gc.id = g.category_id AND 
760
                    g.iid = $group_id
761
                LIMIT 1";
762
        $res = Database::query($sql);
763
        $cat = array();
764
        if (Database::num_rows($res)) {
765
            $cat = Database::fetch_array($res);
766
        }
767
        return $cat;
768
    }
769
770
    /**
771
     * Delete a group category
772
     * @param int $cat_id The id of the category to delete
773
     * @param string $course_code The code in which the category should be
774
     * deleted (default = current course)
775
     * @return bool
776
     */
777
    public static function delete_category($cat_id, $course_code = '')
778
    {
779
        $course_info = api_get_course_info($course_code);
780
        if (empty($course_info)) {
781
            return false;
782
        }
783
        $course_id = $course_info['real_id'];
784
785
        $table_group = Database::get_course_table(TABLE_GROUP);
786
        $table_group_cat = Database::get_course_table(TABLE_GROUP_CATEGORY);
787
        $cat_id = intval($cat_id);
788
        $sql = "SELECT iid FROM $table_group
789
                WHERE c_id = $course_id AND category_id='".$cat_id."'";
790
        $res = Database::query($sql);
791 View Code Duplication
        if (Database::num_rows($res) > 0) {
792
            while ($group = Database::fetch_object($res)) {
793
                $groupInfo = self::get_group_properties($group->iid, true);
794
                self::delete_groups($groupInfo, $course_code);
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by self::get_group_properties($group->iid, true) on line 793 can also be of type null; however, GroupManager::delete_groups() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
795
            }
796
        }
797
        $sql = "DELETE FROM $table_group_cat
798
                WHERE c_id = $course_id  AND id='".$cat_id."'";
799
        Database::query($sql);
800
801
        return true;
802
    }
803
804
    /**
805
     * Create group category
806
     * @param string $title The title of the new category
807
     * @param string $description The description of the new category
808
     * @param int $doc_state
809
     * @param int $work_state
810
     * @param int $calendar_state
811
     * @param int $announcements_state
812
     * @param int $forum_state
813
     * @param int $wiki_state
814
     * @param int $chat_state
815
     * @param int $self_registration_allowed
816
     * @param int $self_unregistration_allowed
817
     * @param int $maximum_number_of_students
818
     * @param int $groups_per_user
819
     * @return mixed
820
     */
821
    public static function create_category(
822
        $title,
823
        $description,
824
        $doc_state,
825
        $work_state,
826
        $calendar_state,
827
        $announcements_state,
828
        $forum_state,
829
        $wiki_state,
830
        $chat_state = 1,
831
        $self_registration_allowed = 0,
832
        $self_unregistration_allowed = 0,
833
        $maximum_number_of_students = 8,
834
        $groups_per_user = 0
835
    ) {
836
        if (empty($title)) {
837
            return false;
838
        }
839
        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
840
        $course_id = api_get_course_int_id();
841
842
        $sql = "SELECT MAX(display_order)+1 as new_order
843
                FROM $table
844
                WHERE c_id = $course_id ";
845
        $res = Database::query($sql);
846
        $obj = Database::fetch_object($res);
847
        if (!isset($obj->new_order)) {
848
            $obj->new_order = 1;
849
        }
850
851
        $params = [
852
            'c_id' => $course_id,
853
            'title' => $title,
854
            'display_order' => $obj->new_order,
855
            'description' => $description,
856
            'doc_state' => $doc_state,
857
            'work_state' => $work_state,
858
            'calendar_state' => $calendar_state,
859
            'announcements_state' => $announcements_state,
860
            'forum_state' => $forum_state,
861
            'wiki_state' => $wiki_state,
862
            'chat_state' => $chat_state,
863
            'groups_per_user' => $groups_per_user,
864
            'self_reg_allowed' => $self_registration_allowed,
865
            'self_unreg_allowed' => $self_unregistration_allowed,
866
            'max_student' => $maximum_number_of_students
867
        ];
868
869
        $categoryId = Database::insert($table, $params);
870
        if ($categoryId) {
871
            $sql = "UPDATE $table SET id = iid
872
                    WHERE iid = $categoryId";
873
            Database::query($sql);
874
875
            return $categoryId;
876
        }
877
878
        return false;
879
    }
880
881
    /**
882
     * Update group category
883
     *
884
     * @param int $id
885
     * @param string $title
886
     * @param string $description
887
     * @param $doc_state
888
     * @param $work_state
889
     * @param $calendar_state
890
     * @param $announcements_state
891
     * @param $forum_state
892
     * @param $wiki_state
893
     * @param $chat_state
894
     * @param $self_registration_allowed
895
     * @param $self_unregistration_allowed
896
     * @param $maximum_number_of_students
897
     * @param $groups_per_user
898
     */
899
    public static function update_category(
900
        $id,
901
        $title,
902
        $description,
903
        $doc_state,
904
        $work_state,
905
        $calendar_state,
906
        $announcements_state,
907
        $forum_state,
908
        $wiki_state,
909
        $chat_state,
910
        $self_registration_allowed,
911
        $self_unregistration_allowed,
912
        $maximum_number_of_students,
913
        $groups_per_user
914
    ) {
915
        $table_group_category = Database::get_course_table(TABLE_GROUP_CATEGORY);
916
        $id = intval($id);
917
918
        $course_id = api_get_course_int_id();
919
920
        $sql = "UPDATE ".$table_group_category." SET
921
                    title='".Database::escape_string($title)."',
922
                    description='".Database::escape_string($description)."',
923
                    doc_state = '".Database::escape_string($doc_state)."',
924
                    work_state = '".Database::escape_string($work_state)."',
925
                    calendar_state = '".Database::escape_string($calendar_state)."',
926
                    announcements_state = '".Database::escape_string($announcements_state)."',
927
                    forum_state = '".Database::escape_string($forum_state)."',
928
                    wiki_state = '".Database::escape_string($wiki_state)."',
929
                    chat_state = '".Database::escape_string($chat_state)."',
930
                    groups_per_user   = '".Database::escape_string($groups_per_user)."',
931
                    self_reg_allowed = '".Database::escape_string($self_registration_allowed)."',
932
                    self_unreg_allowed = '".Database::escape_string($self_unregistration_allowed)."',
933
                    max_student = ".intval($maximum_number_of_students)."
934
                WHERE c_id = $course_id AND id = $id";
935
936
        Database::query($sql);
937
938
        // Updating all groups inside this category
939
        $groups = self::get_group_list($id);
940
941
        if (!empty($groups)) {
942
            foreach ($groups as $group) {
943
                self::set_group_properties(
944
                    $group['id'],
945
                    $group['name'],
946
                    $group['description'],
947
                    $maximum_number_of_students,
948
                    $doc_state,
949
                    $work_state,
950
                    $calendar_state,
951
                    $announcements_state,
952
                    $forum_state,
953
                    $wiki_state,
954
                    $chat_state,
955
                    $self_registration_allowed,
956
                    $self_unregistration_allowed,
957
                    $id
958
                );
959
            }
960
        }
961
    }
962
963
    /**
964
     * Returns the number of groups of the user with the greatest number of
965
     * subscriptions in the given category
966
     */
967
    public static function get_current_max_groups_per_user($category_id = null, $course_code = null)
968
    {
969
        $course_info = api_get_course_info($course_code);
970
        $group_table = Database::get_course_table(TABLE_GROUP);
971
        $group_user_table = Database::get_course_table(TABLE_GROUP_USER);
972
        $sql = 'SELECT COUNT(gu.group_id) AS current_max
973
                FROM '.$group_user_table.' gu, '.$group_table.' g
974
				WHERE g.c_id = '.$course_info['real_id'].'
975
				AND gu.c_id = g.c_id
976
				AND gu.group_id = g.iid ';
977
        if ($category_id != null) {
978
            $category_id = intval($category_id);
979
            $sql .= ' AND g.category_id = '.$category_id;
980
        }
981
        $sql .= ' GROUP BY gu.user_id ORDER BY current_max DESC LIMIT 1';
982
        $res = Database::query($sql);
983
        $obj = Database::fetch_object($res);
984
985
        return $obj->current_max;
986
    }
987
988
    /**
989
     * Swaps the display-order of two categories
990
     * @param int $id1 The id of the first category
991
     * @param int $id2 The id of the second category
992
     */
993
    public static function swap_category_order($id1, $id2)
994
    {
995
        $table_group_cat = Database::get_course_table(TABLE_GROUP_CATEGORY);
996
        $id1 = intval($id1);
997
        $id2 = intval($id2);
998
        $course_id = api_get_course_int_id();
999
1000
        $sql = "SELECT id, display_order FROM $table_group_cat
1001
                WHERE id IN ($id1,$id2) AND c_id = $course_id ";
1002
        $res = Database::query($sql);
1003
        $cat1 = Database::fetch_object($res);
1004
        $cat2 = Database::fetch_object($res);
1005
        if ($cat1 && $cat2) {
1006
            $sql = "UPDATE $table_group_cat SET display_order=$cat2->display_order
1007
                WHERE id = $cat1->id AND c_id = $course_id ";
1008
            Database::query($sql);
1009
1010
            $sql = "UPDATE $table_group_cat SET display_order=$cat1->display_order
1011
                    WHERE id = $cat2->id AND c_id = $course_id ";
1012
            Database::query($sql);
1013
        }
1014
    }
1015
1016
    /**
1017
     * Get all users from a given group
1018
     * @param int $group_id The group
1019
     * @param bool $load_extra_info
1020
     * @param int $start
1021
     * @param int $limit
1022
     * @param bool $getCount
1023
     * @param int $courseId
1024
     * @return array list of user id
1025
     */
1026
    public static function get_users(
1027
        $group_id,
1028
        $load_extra_info = false,
1029
        $start = null,
1030
        $limit = null,
1031
        $getCount = false,
1032
        $courseId = null,
1033
        $column = null,
1034
        $direction = null
1035
    ) {
1036
        $group_user_table = Database::get_course_table(TABLE_GROUP_USER);
1037
        $groupTable = Database::get_course_table(TABLE_GROUP);
1038
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
1039
        $group_id = intval($group_id);
1040
1041
        if (empty($courseId)) {
1042
            $courseId = api_get_course_int_id();
1043
        } else {
1044
            $courseId = intval($courseId);
1045
        }
1046
1047
        $select = " SELECT u.id, firstname, lastname ";
1048
        if ($getCount) {
1049
            $select = " SELECT count(u.id) count";
1050
        }
1051
        $sql = "$select
1052
                FROM $group_user_table gu
1053
                INNER JOIN $groupTable g
1054
                ON (gu.group_id = g.id and g.c_id = gu.c_id)
1055
                INNER JOIN $user_table u
1056
                ON (u.id = gu.user_id)
1057
                WHERE 
1058
                    gu.c_id = $courseId AND 
1059
                    g.id = $group_id";
1060
1061
        if (!empty($column) && !empty($direction)) {
1062
            $column = Database::escape_string($column, null, false);
1063
            $direction = ($direction == 'ASC' ? 'ASC' : 'DESC');
1064
            $sql .= " ORDER BY $column $direction";
1065
        }
1066
1067 View Code Duplication
        if (!empty($start) && !empty($limit)) {
1068
            $start = intval($start);
1069
            $limit = intval($limit);
1070
            $sql .= " LIMIT $start, $limit";
1071
        }
1072
        $res = Database::query($sql);
1073
        $users = array();
1074
        while ($obj = Database::fetch_object($res)) {
1075
            if ($getCount) {
1076
                return $obj->count;
1077
                break;
1078
            }
1079
            if ($load_extra_info) {
1080
                $users[] = api_get_user_info($obj->user_id);
1081
            } else {
1082
                $users[] = $obj->user_id;
1083
            }
1084
        }
1085
1086
        return $users;
1087
    }
1088
1089
    /**
1090
     * @param int $group_id id
1091
     * @return array
1092
     */
1093
    public static function getStudentsAndTutors($group_id)
1094
    {
1095
        $group_user_table = Database::get_course_table(TABLE_GROUP_USER);
1096
        $tutor_user_table = Database::get_course_table(TABLE_GROUP_TUTOR);
1097
        $groupTable = Database::get_course_table(TABLE_GROUP);
1098
1099
        $course_id = api_get_course_int_id();
1100
        $group_id = intval($group_id);
1101
        $sql = "SELECT user_id 
1102
                FROM $group_user_table gu
1103
                INNER JOIN $groupTable g
1104
                ON (gu.group_id = g.iid and g.c_id = gu.c_id)
1105
                WHERE gu.c_id = $course_id AND g.id = $group_id";
1106
        $res = Database::query($sql);
1107
        $users = array();
1108
1109
        while ($obj = Database::fetch_object($res)) {
1110
            $users[] = api_get_user_info($obj->user_id);
1111
        }
1112
1113
        $sql = "SELECT user_id 
1114
                FROM $tutor_user_table gu
1115
                INNER JOIN $groupTable g
1116
                ON (gu.group_id = g.id and g.c_id = gu.c_id)
1117
                WHERE gu.c_id = $course_id AND g.id = $group_id";
1118
        $res = Database::query($sql);
1119
        while ($obj = Database::fetch_object($res)) {
1120
            $users[] = api_get_user_info($obj->user_id);
1121
        }
1122
1123
        return $users;
1124
    }
1125
1126
    /**
1127
     * Get only tutors from a group
1128
     * @param array $groupInfo
1129
     * @return array
1130
     */
1131 View Code Duplication
    public static function getTutors($groupInfo)
1132
    {
1133
        $groupTable = Database::get_course_table(TABLE_GROUP);
1134
        $tutor_user_table = Database::get_course_table(TABLE_GROUP_TUTOR);
1135
        $course_id = api_get_course_int_id();
1136
        $group_id = intval($groupInfo['iid']);
1137
1138
        $sql = "SELECT user_id 
1139
                FROM $tutor_user_table gu
1140
                INNER JOIN $groupTable g
1141
                ON (gu.group_id = g.id and g.c_id = gu.c_id)
1142
                WHERE gu.c_id = $course_id AND g.iid = $group_id";
1143
        $res = Database::query($sql);
1144
1145
        $users = array();
1146
        while ($obj = Database::fetch_object($res)) {
1147
            $users[] = api_get_user_info($obj->user_id);
1148
        }
1149
1150
        return $users;
1151
    }
1152
1153
    /**
1154
     * Get only students from a group (not tutors)
1155
     * @param int $group_id iid
1156
     * @return array
1157
     */
1158
    public static function getStudents($group_id)
1159
    {
1160
        $em = Database::getManager();
1161
        $subscriptions = $em
1162
            ->createQuery('
1163
                SELECT gu
1164
                FROM ChamiloCourseBundle:CGroupRelUser gu
1165
                INNER JOIN ChamiloCourseBundle:CGroupInfo g
1166
                WITH gu.groupId = g.iid AND g.cId = gu.cId
1167
                WHERE gu.cId = :course AND g.id = :group
1168
            ')
1169
            ->setParameters([
1170
                'course' => api_get_course_int_id(),
1171
                'group' => intval($group_id)
1172
            ])
1173
            ->getResult();
1174
1175
        $users = [];
1176
1177
        /** @var CGroupRelUser $subscription */
1178
        foreach ($subscriptions as $subscription) {
1179
            $users[] = api_get_user_info($subscription->getUserId());
1180
        }
1181
1182
        return $users;
1183
    }
1184
1185
    /**
1186
     * Returns users belonging to any of the group
1187
     *
1188
     * @param array $groups list of group ids
1189
     * @return array list of user ids
1190
     */
1191
    public static function get_groups_users($groups = [])
1192
    {
1193
        $result = array();
1194
        $tbl_group_user = Database::get_course_table(TABLE_GROUP_USER);
1195
        $course_id = api_get_course_int_id();
1196
1197
        $groups = array_map('intval', $groups);
1198
        // protect individual elements with surrounding quotes
1199
        $groups = implode(', ', $groups);
1200
        $sql = "SELECT DISTINCT user_id
1201
                FROM $tbl_group_user gu
1202
                WHERE c_id = $course_id AND gu.group_id IN ($groups)";
1203
        $rs = Database::query($sql);
1204
        while ($row = Database::fetch_array($rs)) {
1205
            $result[] = $row['user_id'];
1206
        }
1207
1208
        return $result;
1209
    }
1210
1211
    /**
1212
     * Fill the groups with students.
1213
     * The algorithm takes care to first fill the groups with the least # of users.
1214
     * Analysis
1215
     * There was a problem with the "ALL" setting.
1216
     * When max # of groups is set to all, the value is sometimes NULL and sometimes ALL
1217
     * and in both cased the query does not work as expected.
1218
     * Stupid solution (currently implemented: set ALL to a big number (INFINITE) and things are solved :)
1219
     * Better solution: that's up to you.
1220
     *
1221
     * Note
1222
     * Throughout Dokeos there is some confusion about "course id" and "course code"
1223
     * The code is e.g. TEST101, but sometimes a variable that is called courseID also contains a course code string.
1224
     * However, there is also a integer course_id that uniquely identifies the course.
1225
     * ywarnier:> Now the course_id has been removed (25/1/2005)
1226
     * The databases are als very inconsistent in this.
1227
     *
1228
     * @param array $groupInfo
1229
     * @author Chrisptophe Gesche <[email protected]>,
1230
     *         Hugues Peeters     <[email protected]> - original version
1231
     * @author Roan Embrechts - virtual course support, code cleaning
1232
     * @author Bart Mollet - code cleaning, use other GroupManager-functions
1233
     * @return void
1234
     */
1235
    public static function fill_groups($groupInfo)
1236
    {
1237
        $_course = api_get_course_info();
1238
        $groupIid = $groupInfo['iid'];
1239
        $groupId = $groupInfo['id'];
1240
1241
        $category = self::get_category_from_group($groupIid);
1242
        $groups_per_user = isset($category['groups_per_user']) ? $category['groups_per_user'] : self::GROUP_PER_MEMBER_NO_LIMIT;
1243
        $group_table = Database::get_course_table(TABLE_GROUP);
1244
        $group_user_table = Database::get_course_table(TABLE_GROUP_USER);
1245
        $session_id = api_get_session_id();
1246
1247
        $complete_user_list = CourseManager::get_real_and_linked_user_list(
1248
            $_course['code'],
1249
            true,
1250
            $session_id
1251
        );
1252
        $number_groups_per_user = $groups_per_user == self::GROUP_PER_MEMBER_NO_LIMIT ? self::INFINITE : $groups_per_user;
1253
1254
        /*
1255
         * Retrieve all the groups where enrollment is still allowed
1256
         * (reverse) ordered by the number of place available
1257
         */
1258
1259
        $course_id = api_get_course_int_id();
1260
        $sql = "SELECT g.id gid, g.iid, g.max_student-count(ug.user_id) nbPlaces, g.max_student
1261
                FROM $group_table g
1262
                LEFT JOIN  $group_user_table ug ON
1263
                    g.c_id = $course_id AND 
1264
                    ug.c_id = $course_id AND 
1265
                    g.id = ug.group_id
1266
                WHERE
1267
                    g.id = $groupId
1268
                GROUP BY (g.iid)
1269
                HAVING (nbPlaces > 0 OR g.max_student = ".self::MEMBER_PER_GROUP_NO_LIMIT.")
1270
                ORDER BY nbPlaces DESC";
1271
        $sql_result = Database::query($sql);
1272
        $group_available_place = array();
1273
        while ($group = Database::fetch_array($sql_result, 'ASSOC')) {
1274
            $group_available_place[$group['iid']] = $group['nbPlaces'];
1275
        }
1276
1277
        /*
1278
         * Retrieve course users (reverse) ordered by the number
1279
         * of group they are already enrolled
1280
         */
1281
        for ($i = 0; $i < count($complete_user_list); $i++) {
1282
            //find # of groups the user is enrolled in
1283
            $number_of_groups = self::user_in_number_of_groups(
1284
                $complete_user_list[$i]["user_id"],
1285
                isset($category['id']) ? $category['id'] : null
1286
            );
1287
            //add # of groups to user list
1288
            $complete_user_list[$i]['number_groups_left'] = $number_groups_per_user - $number_of_groups;
1289
        }
1290
1291
        //first sort by user_id to filter out duplicates
1292
        $complete_user_list = TableSort::sort_table($complete_user_list, 'user_id');
1293
        $complete_user_list = self::filter_duplicates($complete_user_list, 'user_id');
1294
        $complete_user_list = self::filter_only_students($complete_user_list);
1295
1296
1297
        //now sort by # of group left
1298
        $complete_user_list = TableSort::sort_table($complete_user_list, 'number_groups_left', SORT_DESC);
1299
        $userToken = array();
1300
        foreach ($complete_user_list as $this_user) {
1301
            if ($this_user['number_groups_left'] > 0) {
1302
                $userToken[$this_user['user_id']] = $this_user['number_groups_left'];
1303
            }
1304
        }
1305
1306
        $changed = true;
1307
        while ($changed) {
1308
            $changed = false;
1309
            reset($group_available_place);
1310
            arsort($group_available_place);
1311
            reset($userToken);
1312
            arsort($userToken);
1313
1314
            foreach ($group_available_place as $groupIid => $place) {
1315
                foreach ($userToken as $user_id => $places) {
1316
                    $groupInfo = self::get_group_properties($groupIid, true);
1317
                    if (self::can_user_subscribe($user_id, $groupInfo)) {
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by self::get_group_properties($groupIid, true) on line 1316 can also be of type null; however, GroupManager::can_user_subscribe() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
1318
                        self::subscribe_users($user_id, $groupInfo);
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by self::get_group_properties($groupIid, true) on line 1316 can also be of type null; however, GroupManager::subscribe_users() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
1319
                        $group_available_place[$groupIid]--;
1320
                        unset($userToken[$user_id]);
1321
                        $changed = true;
1322
                        break;
1323
                    }
1324
                }
1325
                if ($changed) {
1326
                    break;
1327
                }
1328
            }
1329
        }
1330
    }
1331
1332
    /**
1333
     * Get the number of students in a group.
1334
     * @param int $group_id id
1335
     * @return int Number of students in the given group.
1336
     */
1337 View Code Duplication
    public static function number_of_students($group_id, $course_id = null)
1338
    {
1339
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1340
        $group_id = intval($group_id);
1341
        if (empty($course_id)) {
1342
            $course_id = api_get_course_int_id();
1343
        } else {
1344
            $course_id = intval($course_id);
1345
        }
1346
        $sql = "SELECT COUNT(*) AS number_of_students
1347
                FROM $table_group_user
1348
                WHERE c_id = $course_id AND group_id = $group_id";
1349
        $result = Database::query($sql);
1350
        $db_object = Database::fetch_object($result);
1351
1352
        return $db_object->number_of_students;
1353
    }
1354
1355
    /**
1356
     * Maximum number of students in a group
1357
     * @param int $group_id iid
1358
     * @return int Maximum number of students in the given group.
1359
     */
1360 View Code Duplication
    public static function maximum_number_of_students($group_id)
1361
    {
1362
        $table_group = Database::get_course_table(TABLE_GROUP);
1363
        $group_id = intval($group_id);
1364
        $course_id = api_get_course_int_id();
1365
        $sql = "SELECT max_student FROM $table_group 
1366
                WHERE c_id = $course_id AND iid = $group_id";
1367
        $db_result = Database::query($sql);
1368
        $db_object = Database::fetch_object($db_result);
1369
        if ($db_object->max_student == 0) {
1370
            return self::INFINITE;
1371
        }
1372
        return $db_object->max_student;
1373
    }
1374
1375
    /**
1376
     * Number of groups of a user
1377
     * @param int $user_id
1378
     * @return int The number of groups the user is subscribed in.
1379
     */
1380 View Code Duplication
    public static function user_in_number_of_groups($user_id, $cat_id = null)
1381
    {
1382
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1383
        $table_group = Database::get_course_table(TABLE_GROUP);
1384
        $user_id = intval($user_id);
1385
        $cat_id = intval($cat_id);
1386
1387
        $course_id = api_get_course_int_id();
1388
        $cat_condition = '';
1389
        if (!empty($cat_id)) {
1390
            $cat_condition = " AND g.category_id =  $cat_id ";
1391
        }
1392
1393
        $sql = "SELECT  COUNT(*) AS number_of_groups
1394
                FROM $table_group_user gu, $table_group g
1395
                WHERE
1396
                    gu.c_id = $course_id AND
1397
                    g.c_id = $course_id AND
1398
                    gu.user_id = $user_id AND
1399
                    g.iid = gu.group_id  
1400
                    $cat_condition";
1401
        $result = Database::query($sql);
1402
        $db_object = Database::fetch_object($result);
1403
1404
        return $db_object->number_of_groups;
1405
    }
1406
1407
    /**
1408
     * Is sef-registration allowed?
1409
     * @param int $user_id
1410
     * @param array $groupInfo
1411
     * @return bool TRUE if self-registration is allowed in the given group.
1412
     */
1413 View Code Duplication
    public static function is_self_registration_allowed($user_id, $groupInfo)
1414
    {
1415
        $course_id = api_get_course_int_id();
1416
        if (!$user_id > 0) {
1417
            return false;
1418
        }
1419
        $groupIid = $groupInfo['iid'];
1420
        $table_group = Database::get_course_table(TABLE_GROUP);
1421
        if (isset($groupIid)) {
1422
            $sql = "SELECT status, self_registration_allowed
1423
                    FROM $table_group
1424
                    WHERE c_id = $course_id AND iid = $groupIid";
1425
            $result = Database::query($sql);
1426
            $group = Database::fetch_object($result);
1427
1428
            if ($group->status == 0 || $group->self_registration_allowed != 1) {
1429
                return false;
1430
            }
1431
1432
            return self::can_user_subscribe($user_id, $groupInfo);
1433
        } else {
1434
            return false;
1435
        }
1436
    }
1437
1438
    /**
1439
     * Is sef-unregistration allowed?
1440
     * @param int $user_id
1441
     * @param array $groupInfo
1442
     * @return bool TRUE if self-unregistration is allowed in the given group.
1443
     */
1444 View Code Duplication
    public static function is_self_unregistration_allowed($user_id, $groupInfo)
1445
    {
1446
        if (!$user_id > 0 || empty($groupInfo)) {
1447
            return false;
1448
        }
1449
        $groupIid = $groupInfo['iid'];
1450
        $table_group = Database::get_course_table(TABLE_GROUP);
1451
        $course_id = api_get_course_int_id();
1452
1453
        $sql = "SELECT status, self_unregistration_allowed
1454
                FROM $table_group
1455
                WHERE c_id = $course_id AND iid = $groupIid";
1456
        $result = Database::query($sql);
1457
        $group = Database::fetch_object($result);
1458
1459
        if ($group->status == 0 || $group->self_unregistration_allowed != 1) {
1460
            return false;
1461
        }
1462
1463
        return self::is_subscribed($user_id, $groupInfo);
1464
    }
1465
1466
    /**
1467
     * Is user subscribed in group?
1468
     * @param int $user_id
1469
     * @param array $groupInfo
1470
     * @return bool TRUE if given user is subscribed in given group
1471
     */
1472
    public static function is_subscribed($user_id, $groupInfo)
1473
    {
1474
        $course_id = api_get_course_int_id();
1475
        if (empty($user_id) || empty($groupInfo) || empty($course_id)) {
1476
            return false;
1477
        }
1478
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1479
        $group_id = intval($groupInfo['id']);
1480
        $user_id = intval($user_id);
1481
1482
        $sql = "SELECT 1 FROM $table_group_user
1483
                WHERE
1484
                    c_id = $course_id AND
1485
                    group_id = $group_id AND
1486
                    user_id = $user_id
1487
                ";
1488
        $result = Database::query($sql);
1489
1490
        return Database::num_rows($result) > 0;
1491
    }
1492
1493
    /**
1494
     * Can a user subscribe to a specified group in a course
1495
     * @param int $user_id
1496
     * @param array $groupInfo
1497
     * @param bool $checkMaxNumberStudents
1498
     *
1499
     * @return bool TRUE if given user  can be subscribed in given group
1500
     */
1501
    public static function can_user_subscribe(
1502
        $user_id,
1503
        $groupInfo,
1504
        $checkMaxNumberStudents = true
1505
    ) {
1506
        $group_id = $groupInfo['id'];
1507
        $groupIid = $groupInfo['iid'];
1508
        if ($checkMaxNumberStudents) {
1509
            $category = self::get_category_from_group($groupIid);
1510
            if ($category) {
1511
                if ($category['groups_per_user'] == self::GROUP_PER_MEMBER_NO_LIMIT) {
1512
                    $category['groups_per_user'] = self::INFINITE;
1513
                }
1514
                $result = self:: user_in_number_of_groups($user_id, $category['id']) < $category['groups_per_user'];
1515
                if ($result == false) {
1516
                    return false;
1517
                }
1518
            }
1519
1520
            $result = self::number_of_students($group_id) < self:: maximum_number_of_students($groupIid);
1521
1522
            if ($result == false) {
1523
                return false;
1524
            }
1525
        }
1526
1527
        $result = self::is_tutor_of_group($user_id, $groupInfo);
1528
1529
        if ($result) {
1530
            return false;
1531
        }
1532
1533
        $result = self::is_subscribed($user_id, $groupInfo);
1534
1535
        if ($result) {
1536
            return false;
1537
        }
1538
1539
        return true;
1540
    }
1541
1542
    /**
1543
     * Get all subscribed users (members) from a group
1544
     * @param array $groupInfo
1545
     * @return array An array with information of all users from the given group.
1546
     *               (user_id, firstname, lastname, email)
1547
     */
1548
    public static function get_subscribed_users($groupInfo)
1549
    {
1550
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
1551
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1552
        $order_clause = api_sort_by_first_name() ? ' ORDER BY u.firstname, u.lastname' : ' ORDER BY u.lastname, u.firstname';
1553
        $orderListByOfficialCode = api_get_setting('order_user_list_by_official_code');
1554
        if ($orderListByOfficialCode === 'true') {
1555
            $order_clause = " ORDER BY u.official_code, u.firstname, u.lastname";
1556
        }
1557
1558
        $group_id = intval($groupInfo['id']);
1559
1560
        if (empty($group_id)) {
1561
            return array();
1562
        }
1563
1564
        $course_id = api_get_course_int_id();
1565
1566
        $sql = "SELECT 
1567
                    ug.id, 
1568
                    u.user_id, 
1569
                    u.lastname, 
1570
                    u.firstname, 
1571
                    u.email, 
1572
                    u.username
1573
                FROM $table_user u 
1574
                INNER JOIN $table_group_user ug
1575
                ON (ug.user_id = u.user_id)
1576
                WHERE ug.c_id = $course_id AND
1577
                      ug.group_id = $group_id
1578
                $order_clause";
1579
1580
        $db_result = Database::query($sql);
1581
        $users = array();
1582
        while ($user = Database::fetch_object($db_result)) {
1583
            $users[$user->user_id] = array(
1584
                'user_id'   => $user->user_id,
1585
                'firstname' => $user->firstname,
1586
                'lastname'  => $user->lastname,
1587
                'email'     => $user->email,
1588
                'username'  => $user->username
1589
            );
1590
        }
1591
1592
        return $users;
1593
    }
1594
1595
    /**
1596
     * @author Patrick Cool <[email protected]>, Ghent University
1597
     * Get all subscribed tutors of a group
1598
     * @param array $groupInfo
1599
     * @return array An array with information of all users from the given group.
1600
     *               (user_id, firstname, lastname, email)
1601
     */
1602
    public static function get_subscribed_tutors($groupInfo, $id_only = false)
1603
    {
1604
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
1605
        $table_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
1606
        $order_clause = api_sort_by_first_name() ? ' ORDER BY u.firstname, u.lastname' : ' ORDER BY u.lastname, u.firstname';
1607
1608
        $orderListByOfficialCode = api_get_setting('order_user_list_by_official_code');
1609
        if ($orderListByOfficialCode === 'true') {
1610
            $order_clause = " ORDER BY u.official_code, u.firstname, u.lastname";
1611
        }
1612
1613
        $group_id = intval($groupInfo['id']);
1614
        $course_id = api_get_course_int_id();
1615
1616
        $sql = "SELECT tg.id, u.user_id, u.lastname, u.firstname, u.email
1617
                FROM $table_user u, $table_group_tutor tg
1618
                WHERE
1619
                    tg.c_id = $course_id AND
1620
                    tg.group_id = $group_id AND
1621
                    tg.user_id = u.user_id 
1622
                $order_clause
1623
                ";
1624
        $db_result = Database::query($sql);
1625
        $users = array();
1626
        while ($user = Database::fetch_object($db_result)) {
1627
            if (!$id_only) {
1628
                $member['user_id'] = $user->user_id;
1629
                $member['firstname'] = $user->firstname;
1630
                $member['lastname'] = $user->lastname;
1631
                $member['email'] = $user->email;
1632
                $users[] = $member;
1633
            } else {
1634
                $users[] = $user->user_id;
1635
            }
1636
        }
1637
1638
        return $users;
1639
    }
1640
1641
    /**
1642
     * Subscribe user(s) to a specified group in current course (as a student)
1643
     * @param mixed $user_ids Can be an array with user-id's or a single user-id
1644
     * @param array $groupInfo
1645
     * @param int $course_id
1646
     * @return bool TRUE if successful
1647
     */
1648
    public static function subscribe_users($user_ids, $groupInfo, $course_id = null)
1649
    {
1650
        $user_ids = is_array($user_ids) ? $user_ids : array($user_ids);
1651
        $course_id = isset($course_id) && !empty($course_id) ? intval($course_id) : api_get_course_int_id();
1652
        $group_id = $groupInfo['id'];
1653
1654
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1655
        if (!empty($user_ids)) {
1656
            foreach ($user_ids as $user_id) {
1657
                if (self::can_user_subscribe($user_id, $groupInfo)) {
1658
                    $user_id = intval($user_id);
1659
                    $sql = "INSERT INTO ".$table_group_user." (c_id, user_id, group_id)
1660
                            VALUES ('$course_id', '".$user_id."', '".$group_id."')";
1661
                    Database::query($sql);
1662
                }
1663
            }
1664
        }
1665
1666
        return true;
1667
    }
1668
1669
    /**
1670
     * Subscribe tutor(s) to a specified group in current course
1671
     * @param mixed $user_ids Can be an array with user-id's or a single user-id
1672
     * @param array $groupInfo
1673
     * @param int $course_id
1674
     *
1675
     * @author Patrick Cool <[email protected]>, Ghent University
1676
     * @see subscribe_users. This function is almost an exact copy of that function.
1677
     * @return bool TRUE if successful
1678
     */
1679
    public static function subscribe_tutors($user_ids, $groupInfo, $course_id = 0)
1680
    {
1681
        $user_ids = is_array($user_ids) ? $user_ids : array($user_ids);
1682
        $result = true;
1683
        $course_id = isset($course_id) && !empty($course_id) ? intval($course_id) : api_get_course_int_id();
1684
        $table_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
1685
        $groupId = (int) $groupInfo['id'];
1686
1687
        foreach ($user_ids as $user_id) {
1688
            $user_id = intval($user_id);
1689
            if (self::can_user_subscribe($user_id, $groupInfo, false)) {
1690
                $sql = "INSERT INTO ".$table_group_tutor." (c_id, user_id, group_id)
1691
                        VALUES ('$course_id', '".$user_id."', '".$groupId."')";
1692
                $result = Database::query($sql);
1693
            }
1694
        }
1695
1696
        return $result;
1697
    }
1698
1699
    /**
1700
     * Unsubscribe user(s) from a specified group in current course
1701
     * @param mixed $user_ids Can be an array with user-id's or a single user-id
1702
     * @param array $groupInfo
1703
     * @return bool TRUE if successful
1704
     */
1705
    public static function unsubscribe_users($user_ids, $groupInfo)
1706
    {
1707
        $user_ids = is_array($user_ids) ? $user_ids : array($user_ids);
1708
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1709
        $group_id = intval($groupInfo['id']);
1710
        $course_id = api_get_course_int_id();
1711
        $sql = 'DELETE FROM '.$table_group_user.'
1712
                WHERE
1713
                    c_id = '.$course_id.' AND
1714
                    group_id = '.$group_id.' AND
1715
                    user_id IN ('.implode(',', $user_ids).')
1716
                ';
1717
        Database::query($sql);
1718
    }
1719
1720
    /**
1721
     * Unsubscribe all users from one or more groups
1722
     * @param array $groupInfo
1723
     * @return bool TRUE if successful
1724
     */
1725 View Code Duplication
    public static function unsubscribe_all_users($groupInfo)
1726
    {
1727
        $course_id = api_get_course_int_id();
1728
        $groupId = (int) $groupInfo['id'];
1729
        if (empty($course_id) || empty($groupId)) {
1730
            return false;
1731
        }
1732
1733
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
1734
        $sql = "DELETE FROM $table_group_user
1735
                WHERE 
1736
                    group_id = $groupId AND 
1737
                    c_id = $course_id";
1738
        $result = Database::query($sql);
1739
1740
        return $result;
1741
    }
1742
1743
    /**
1744
     * Unsubscribe all tutors from one or more groups
1745
     * @param int $groupId iid
1746
     * @see unsubscribe_all_users. This function is almost an exact copy of that function.
1747
     * @return bool TRUE if successful
1748
     * @author Patrick Cool <[email protected]>, Ghent University
1749
     */
1750 View Code Duplication
    public static function unsubscribe_all_tutors($groupId)
1751
    {
1752
        $courseId = api_get_course_int_id();
1753
        $groupId = (int) $groupId;
1754
1755
        if (empty($courseId) || empty($groupId)) {
1756
            return false;
1757
        }
1758
1759
        if (!empty($groupId) > 0) {
1760
            $table_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
1761
            $sql = "DELETE FROM $table_group_tutor
1762
                    WHERE group_id = $groupId AND c_id = $courseId";
1763
            $result = Database::query($sql);
1764
            return $result;
1765
        }
1766
        return true;
1767
    }
1768
1769
    /**
1770
     * Is the user a tutor of this group?
1771
     * @param int $user_id the id of the user
1772
     * @param array $groupInfo
1773
     * @return boolean true/false
1774
     * @todo use the function user_has_access that includes this function
1775
     * @author Patrick Cool <[email protected]>, Ghent University
1776
     */
1777 View Code Duplication
    public static function is_tutor_of_group($user_id, $groupInfo)
1778
    {
1779
        if (empty($groupInfo)) {
1780
            return false;
1781
        }
1782
1783
        $table_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
1784
        $user_id = intval($user_id);
1785
        $group_id = intval($groupInfo['id']);
1786
        $course_id = api_get_course_int_id();
1787
1788
        $sql = "SELECT * FROM $table_group_tutor
1789
                WHERE 
1790
                    c_id = $course_id AND 
1791
                    user_id = $user_id AND 
1792
                    group_id = $group_id";
1793
        $result = Database::query($sql);
1794
        if (Database::num_rows($result) > 0) {
1795
            return true;
1796
        } else {
1797
            return false;
1798
        }
1799
    }
1800
1801
    /**
1802
     * Is the user part of this group? This can be a tutor or a normal member
1803
     * you should use this function if the access to a tool or functionality is
1804
     * restricted to the people who are actually in the group
1805
     * before you had to check if the user was
1806
     * 1. a member of the group OR
1807
     * 2. a tutor of the group. This function combines both
1808
     * @param int $user_id the id of the user
1809
     * @param array $groupInfo
1810
     * @return boolean true/false
1811
     * @author Patrick Cool <[email protected]>, Ghent University
1812
     */
1813
    public static function is_user_in_group($user_id, $groupInfo)
1814
    {
1815
        $member = self::is_subscribed($user_id, $groupInfo);
1816
        $tutor = self::is_tutor_of_group($user_id, $groupInfo);
1817
        if ($member || $tutor) {
1818
            return true;
1819
        } else {
1820
            return false;
1821
        }
1822
    }
1823
1824
    /**
1825
     * Get all group's from a given course in which a given user is unsubscribed
1826
     * @author  Patrick Cool
1827
     * @param int  $course_id retrieve the groups for
1828
     * @param int $user_id the ID of the user you want to know all its group memberships
1829
     * @return array
1830
     */
1831
    public static function get_group_ids($course_id, $user_id)
1832
    {
1833
        $groups = array();
1834
        $tbl_group = Database::get_course_table(TABLE_GROUP_USER);
1835
        $tbl_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
1836
        $user_id = intval($user_id);
1837
        $course_id = intval($course_id);
1838
1839
        $sql = "SELECT group_id FROM $tbl_group
1840
                WHERE c_id = $course_id AND user_id = '$user_id'";
1841
        $result = Database::query($sql);
1842
1843
        if ($result) {
1844
            while ($row = Database::fetch_array($result)) {
1845
                $groups[] = $row['group_id'];
1846
            }
1847
        }
1848
1849
        //Also loading if i'm the tutor
1850
        $sql = "SELECT group_id FROM $tbl_group_tutor
1851
                WHERE c_id = $course_id AND user_id = '$user_id'";
1852
        $result = Database::query($sql);
1853
        if ($result) {
1854
            while ($row = Database::fetch_array($result)) {
1855
                $groups[] = $row['group_id'];
1856
            }
1857
        }
1858
        if (!empty($groups)) {
1859
            array_filter($groups);
1860
        }
1861
1862
        return $groups;
1863
    }
1864
1865
    /**
1866
     * Filter out duplicates in a multidimensional array
1867
     * by comparing field $compare_field.
1868
     *
1869
     * @param array $user_array_in List of users (must be sorted).
1870
     * @param string $compare_field The field to be compared
1871
     * @return array
1872
     */
1873
    public static function filter_duplicates($user_array_in, $compare_field)
1874
    {
1875
        $total_number = count($user_array_in);
1876
        $user_array_out[0] = $user_array_in[0];
1877
        $count_out = 0;
1878
        for ($count_in = 1; $count_in < $total_number; $count_in++) {
1879
            if ($user_array_in[$count_in][$compare_field] != $user_array_out[$count_out][$compare_field]) {
1880
                $count_out++;
1881
                $user_array_out[$count_out] = $user_array_in[$count_in];
1882
            }
1883
        }
1884
        return $user_array_out;
1885
    }
1886
1887
    /**
1888
     * Remove all users that are not students and all users who have tutor status
1889
     * from  the list.
1890
     * @param array $user_array_in
1891
     * @return array
1892
     */
1893
    public static function filter_only_students($user_array_in)
1894
    {
1895
        $user_array_out = array();
1896
        foreach ($user_array_in as $this_user) {
1897
            if (api_get_session_id()) {
1898
                if ($this_user['status_session'] == 0) {
1899
                    $user_array_out[] = $this_user;
1900
                }
1901
            } else {
1902
                if ($this_user['status_rel'] == STUDENT) {
1903
                    $user_array_out[] = $this_user;
1904
                }
1905
            }
1906
        }
1907
        return $user_array_out;
1908
    }
1909
1910
    /**
1911
     * Check if a user has access to a certain group tool
1912
     * @param int $user_id The user id
1913
     * @param int $group_id The group iid
1914
     * @param string $tool The tool to check the access rights. This should be
1915
     * one of constants: GROUP_TOOL_DOCUMENTS
1916
     * @return bool True if the given user has access to the given tool in the
1917
     * given course.
1918
     */
1919
    public static function user_has_access($user_id, $group_id, $tool)
1920
    {
1921
        // Admin have access everywhere
1922
        if (api_is_platform_admin()) {
1923
            return true;
1924
        }
1925
1926
        // Course admin also have access to everything
1927
        if (api_is_allowed_to_edit()) {
1928
            return true;
1929
        }
1930
1931
        switch ($tool) {
1932
            case self::GROUP_TOOL_FORUM:
1933
                $key = 'forum_state';
1934
                break;
1935
            case self::GROUP_TOOL_DOCUMENTS:
1936
                $key = 'doc_state';
1937
                break;
1938
            case self::GROUP_TOOL_CALENDAR:
1939
                $key = 'calendar_state';
1940
                break;
1941
            case self::GROUP_TOOL_ANNOUNCEMENT:
1942
                $key = 'announcements_state';
1943
                break;
1944
            case self::GROUP_TOOL_WORK:
1945
                $key = 'work_state';
1946
                break;
1947
            case self::GROUP_TOOL_WIKI:
1948
                $key = 'wiki_state';
1949
                break;
1950
            case self::GROUP_TOOL_CHAT:
1951
                $key = 'chat_state';
1952
                break;
1953
            default:
1954
                return false;
1955
        }
1956
1957
        // Check group properties
1958
        $groupInfo = self::get_group_properties($group_id, true);
1959
1960
        if (empty($groupInfo)) {
1961
            return false;
1962
        }
1963
1964
        if ($groupInfo['status'] == 0) {
1965
            return false;
1966
        }
1967
1968
        if (!isset($groupInfo[$key])) {
1969
            return false;
1970
        }
1971
1972
        if (api_is_allowed_to_edit(false, true)) {
1973
            return true;
1974
        }
1975
1976
        $status = $groupInfo[$key];
1977
1978
        switch ($status) {
1979
            case self::TOOL_NOT_AVAILABLE:
1980
                return false;
1981
                break;
1982
            case self::TOOL_PUBLIC:
1983
                return true;
1984
                break;
1985
            case self::TOOL_PRIVATE:
1986
                $userIsInGroup = self::is_user_in_group($user_id, $groupInfo);
1987
                if ($userIsInGroup) {
1988
                    return true;
1989
                }
1990
                break;
1991
        }
1992
1993
        return false;
1994
    }
1995
1996
    /**
1997
     * @param int $userId
1998
     * @param array $groupInfo
1999
     * @param int $sessionId
2000
     *
2001
     * @return bool
2002
     */
2003
    public static function userHasAccessToBrowse($userId, $groupInfo, $sessionId = 0)
2004
    {
2005
        if (empty($groupInfo)) {
2006
            return false;
2007
        }
2008
2009
        if (api_is_platform_admin()) {
2010
            return true;
2011
        }
2012
2013
        if (api_is_allowed_to_edit(false, true)) {
2014
            return true;
2015
        }
2016
2017
        $groupId = $groupInfo['iid'];
2018
        $tutors = self::get_subscribed_tutors($groupInfo, true);
2019
2020
        if (in_array($userId, $tutors)) {
2021
            return true;
2022
        }
2023
2024
        if ($groupInfo['status'] == 0) {
2025
            return false;
2026
        }
2027
2028
        if (self::user_has_access($userId, $groupId, self::GROUP_TOOL_FORUM) ||
2029
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_DOCUMENTS) ||
2030
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_CALENDAR) ||
2031
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_ANNOUNCEMENT) ||
2032
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_WORK) ||
2033
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_WIKI) ||
2034
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_CHAT)
2035
        ) {
2036
            return true;
2037
        }
2038
2039
        if (api_is_session_general_coach() && $groupInfo['session_id'] == $sessionId) {
2040
            return true;
2041
        }
2042
2043
        return false;
2044
    }
2045
2046
2047
    /**
2048
     * Get all groups where a specific user is subscribed
2049
     * @param int $user_id
2050
     * @return array
2051
     */
2052 View Code Duplication
    public static function get_user_group_name($user_id)
2053
    {
2054
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
2055
        $table_group = Database::get_course_table(TABLE_GROUP);
2056
        $user_id = intval($user_id);
2057
        $course_id = api_get_course_int_id();
2058
        $sql = "SELECT name
2059
                FROM $table_group g 
2060
                INNER JOIN $table_group_user gu
2061
                ON (gu.group_id = g.iid)
2062
                WHERE
2063
                  gu.c_id= $course_id AND
2064
                  g.c_id= $course_id AND
2065
                  gu.user_id = $user_id";
2066
        $res = Database::query($sql);
2067
        $groups = array();
2068
        while ($group = Database::fetch_array($res)) {
2069
            $groups[] .= $group['name'];
2070
        }
2071
        return $groups;
2072
    }
2073
2074
    /**
2075
     * Get all groups where a specific user is subscribed
2076
     * @param int $user_id
2077
     * @return array
2078
     */
2079
    public static function getAllGroupPerUserSubscription($user_id)
2080
    {
2081
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
2082
        $table_tutor_user = Database::get_course_table(TABLE_GROUP_TUTOR);
2083
        $table_group = Database::get_course_table(TABLE_GROUP);
2084
        $user_id = intval($user_id);
2085
        $course_id = api_get_course_int_id();
2086
        $sql = "SELECT DISTINCT g.*
2087
               FROM $table_group g
2088
               LEFT JOIN $table_group_user gu
2089
               ON (gu.group_id = g.iid AND g.c_id = gu.c_id)
2090
               LEFT JOIN $table_tutor_user tu
2091
               ON (tu.group_id = g.iid AND g.c_id = tu.c_id)
2092
               WHERE
2093
                  g.c_id = $course_id AND
2094
                  (gu.user_id = $user_id OR tu.user_id = $user_id) ";
2095
        $res = Database::query($sql);
2096
        $groups = array();
2097
        while ($group = Database::fetch_array($res, 'ASSOC')) {
2098
            $groups[] = $group;
2099
        }
2100
2101
        return $groups;
2102
    }
2103
2104
    /**
2105
     *
2106
     * See : fill_groups
2107
     *       Fill the groups with students.
2108
     *
2109
     * note : optimize fill_groups_list <--> fill_groups
2110
     * @param array $groupInfo
2111
     * @return array|bool
2112
     */
2113
    public static function fill_groups_list($groupInfo)
2114
    {
2115
        if (empty($groupInfo)) {
2116
            return [];
2117
        }
2118
        $groupIid = (int) $groupInfo['iid'];
2119
        $groupId = (int) $groupInfo['id'];
2120
2121
        $_course = api_get_course_info();
2122
        if (empty($_course) || empty($groupId)) {
2123
            return [];
2124
        }
2125
2126
        $category = self::get_category_from_group($groupIid);
2127
        $number_groups_per_user = self::GROUP_PER_MEMBER_NO_LIMIT;
2128
        $categoryId = 0;
2129
        if ($category) {
2130
            $groups_per_user = $category['groups_per_user'];
2131
            $number_groups_per_user = ($groups_per_user == self::GROUP_PER_MEMBER_NO_LIMIT ? self::INFINITE : $groups_per_user);
2132
            $categoryId = $category['id'];
2133
        }
2134
2135
        $session_id = api_get_session_id();
2136
        $complete_user_list = CourseManager::get_real_and_linked_user_list(
2137
            $_course['code'],
2138
            true,
2139
            $session_id
2140
        );
2141
2142
        /*
2143
         * Retrieve course users (reverse) ordered by the number
2144
         * of group they are already enrolled
2145
         */
2146
        for ($i = 0; $i < count($complete_user_list); $i++) {
2147
            // find # of groups the user is enrolled in
2148
            $number_of_groups = self:: user_in_number_of_groups(
2149
                $complete_user_list[$i]['user_id'],
2150
                $categoryId
2151
            );
2152
            // add # of groups to user list
2153
            $complete_user_list[$i]['number_groups_left'] = $number_groups_per_user - $number_of_groups;
2154
        }
2155
        //first sort by user_id to filter out duplicates
2156
        $complete_user_list = TableSort::sort_table(
2157
            $complete_user_list,
2158
            'user_id'
2159
        );
2160
        $complete_user_list = self::filter_duplicates(
2161
            $complete_user_list,
2162
            'user_id'
2163
        );
2164
        //now sort by # of group left
2165
        $complete_user_list = TableSort::sort_table(
2166
            $complete_user_list,
2167
            'number_groups_left',
2168
            SORT_DESC
2169
        );
2170
2171
        return $complete_user_list;
2172
    }
2173
2174
    /**
2175
     * @param array $group_list
2176
     * @param int $category_id
2177
     *
2178
     * @return string
2179
     */
2180
    public static function process_groups($group_list, $category_id = null)
2181
    {
2182
        global $charset;
2183
        $category_id = intval($category_id);
2184
2185
        $totalRegistered = 0;
2186
        $group_data = array();
2187
        $user_info = api_get_user_info();
2188
        $session_id = api_get_session_id();
2189
        $user_id = $user_info['user_id'];
2190
        $hideGroup = api_get_setting('hide_course_group_if_no_tools_available');
2191
2192
        foreach ($group_list as $this_group) {
2193
            // Validation when belongs to a session
2194
            $session_img = api_get_session_image($this_group['session_id'], $user_info['status']);
2195
2196
            // All the tutors of this group
2197
            $tutorsids_of_group = self::get_subscribed_tutors($this_group, true);
2198
            $isMember = self::is_subscribed($user_id, $this_group);
2199
2200
            // Create a new table-row
2201
            $row = array();
2202
2203
            // Checkbox
2204
            if (api_is_allowed_to_edit(false, true) && count($group_list) > 1) {
2205
                $row[] = $this_group['id'];
2206
            }
2207
2208
            if (self::userHasAccessToBrowse($user_id, $this_group, $session_id)) {
2209
                // Group name
2210
                $groupNameClass = null;
2211
                if ($this_group['status'] == 0) {
2212
                    $groupNameClass = 'muted';
2213
                }
2214
2215
                $group_name = '<a class="'.$groupNameClass.'" href="group_space.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'">'.
2216
                    Security::remove_XSS($this_group['name']).'</a> ';
2217
                if (!empty($user_id) && !empty($this_group['id_tutor']) && $user_id == $this_group['id_tutor']) {
2218
                    $group_name .= Display::label(get_lang('OneMyGroups'), 'success');
2219
                } elseif ($isMember) {
2220
                    $group_name .= Display::label(get_lang('MyGroup'), 'success');
2221
                }
2222
2223
                if (api_is_allowed_to_edit() && !empty($this_group['session_name'])) {
2224
                    $group_name .= ' ('.$this_group['session_name'].')';
2225
                }
2226
                $group_name .= $session_img;
2227
                $row[] = $group_name.'<br />'.stripslashes(trim($this_group['description']));
2228
            } else {
2229
                if ($hideGroup === 'true') {
2230
                    continue;
2231
                }
2232
                $row[] = $this_group['name'].'<br />'.stripslashes(trim($this_group['description']));
2233
            }
2234
2235
            // Tutor name
2236
            $tutor_info = null;
2237
2238
            if (count($tutorsids_of_group) > 0) {
2239
                foreach ($tutorsids_of_group as $tutor_id) {
2240
                    $tutor = api_get_user_info($tutor_id);
2241
                    $username = api_htmlentities(sprintf(get_lang('LoginX'), $tutor['username']), ENT_QUOTES);
2242
                    if (api_get_setting('show_email_addresses') === 'true') {
2243
                        $tutor_info .= Display::tag(
2244
                            'span',
2245
                            Display::encrypted_mailto_link($tutor['mail'], api_get_person_name($tutor['firstName'], $tutor['lastName'])),
2246
                            array('title'=>$username)
2247
                        ).', ';
2248
                    } else {
2249
                        if (api_is_allowed_to_edit()) {
2250
                            $tutor_info .= Display::tag(
2251
                                'span',
2252
                                Display::encrypted_mailto_link($tutor['mail'], api_get_person_name($tutor['firstName'], $tutor['lastName'])),
2253
                                array('title'=>$username)
2254
                            ).', ';
2255
                        } else {
2256
                            $tutor_info .= Display::tag(
2257
                                'span',
2258
                                api_get_person_name($tutor['firstName'], $tutor['lastName']),
2259
                                array('title'=>$username)
2260
                            ).', ';
2261
                        }
2262
                    }
2263
                }
2264
            }
2265
2266
            $tutor_info = api_substr($tutor_info, 0, api_strlen($tutor_info) - 2);
2267
            $row[] = $tutor_info;
2268
2269
            // Max number of members in group
2270
            $max_members = $this_group['maximum_number_of_members'] == self::MEMBER_PER_GROUP_NO_LIMIT ? ' ' : ' / '.$this_group['maximum_number_of_members'];
2271
2272
            // Number of members in group
2273
            $row[] = $this_group['number_of_members'].$max_members;
2274
2275
            // Self-registration / unregistration
2276
            if (!api_is_allowed_to_edit(false, true)) {
2277
                if (self::is_self_registration_allowed($user_id, $this_group)) {
2278
                    $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>';
2279
                } elseif (self::is_self_unregistration_allowed($user_id, $this_group)) {
2280
                    $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>';
2281
                } else {
2282
                    $row[] = '-';
2283
                }
2284
            }
2285
2286
            $url = api_get_path(WEB_CODE_PATH).'group/';
2287
            // Edit-links
2288
            if (api_is_allowed_to_edit(false, true) &&
2289
                !(api_is_session_general_coach() && intval($this_group['session_id']) != $session_id)
2290
            ) {
2291
                $edit_actions = '<a href="'.$url.'settings.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'"  title="'.get_lang('Edit').'">'.
2292
                    Display::return_icon('edit.png', get_lang('EditGroup'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2293
2294
                if ($this_group['status'] == 1) {
2295
                    $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').'">'.
2296
                        Display::return_icon('visible.png', get_lang('Hide'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2297 View Code Duplication
                } else {
2298
                    $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').'">'.
2299
                        Display::return_icon('invisible.png', get_lang('Show'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2300
                }
2301
2302
                $edit_actions .= '<a href="'.$url.'member_settings.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'"  title="'.get_lang('GroupMembers').'">'.
2303
                    Display::return_icon('user.png', get_lang('GroupMembers'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2304
2305
                $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').'">'.
2306
                    Display::return_icon('export_excel.png', get_lang('Export'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2307
2308
                $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').'">'.
2309
                    Display::return_icon('fill.png', get_lang('FillGroup'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2310
2311
                $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').'">'.
2312
                    Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2313
2314
                $row[] = $edit_actions;
2315
            }
2316
            if (!empty($this_group['nbMember'])) {
2317
                $totalRegistered = $totalRegistered + $this_group['nbMember'];
2318
            }
2319
            $group_data[] = $row;
2320
        } // end loop
2321
2322
        // If no groups then don't show the table (only for students)
2323
        if (!api_is_allowed_to_edit(true, false)) {
2324
            if (empty($group_data)) {
2325
                return '';
2326
            }
2327
        }
2328
2329
        $table = new SortableTableFromArrayConfig(
2330
            $group_data,
2331
            1,
2332
            20,
2333
            'group_category_'.$category_id
2334
        );
2335
        $table->set_additional_parameters(array('category' => $category_id));
2336
        $column = 0;
2337
        if (api_is_allowed_to_edit(false, true) and count($group_list) > 1) {
2338
            $table->set_header($column++, '', false);
2339
        }
2340
        $table->set_header($column++, get_lang('Groups'));
2341
        $table->set_header($column++, get_lang('GroupTutor'));
2342
        $table->set_header($column++, get_lang('Registered'), false);
2343
2344
        if (!api_is_allowed_to_edit(false, true)) {
2345
            // If self-registration allowed
2346
            $table->set_header($column++, get_lang('GroupSelfRegistration'), false);
2347
        }
2348
2349
        if (api_is_allowed_to_edit(false, true)) {
2350
            // Only for course administrator
2351
            $table->set_header($column++, get_lang('Modify'), false);
2352
            $form_actions = array();
2353
            $form_actions['fill_selected'] = get_lang('FillGroup');
2354
            $form_actions['empty_selected'] = get_lang('EmptyGroup');
2355
            $form_actions['delete_selected'] = get_lang('Delete');
2356
            if (count($group_list) > 1) {
2357
                $table->set_form_actions($form_actions, 'group');
2358
            }
2359
        }
2360
2361
        return $table->return_table();
2362
    }
2363
2364
    /**
2365
     * @param array $groupData
2366
     * @param bool $deleteNotInArray
2367
     * @return array
2368
     */
2369
    public static function importCategoriesAndGroupsFromArray($groupData, $deleteNotInArray = false)
2370
    {
2371
        $result = array();
2372
        $elementsFound = array(
2373
            'categories' => array(),
2374
            'groups' => array()
2375
        );
2376
2377
        $courseCode = api_get_course_id();
2378
        $sessionId = api_get_session_id();
2379
        $groupCategories = self::get_categories();
2380
2381
        if (empty($groupCategories)) {
2382
            $result['error'][] = get_lang('CreateACategory');
2383
            return $result;
2384
        }
2385
2386
        foreach ($groupData as $data) {
2387
            $isCategory = empty($data['group']) ? true : false;
2388
            if ($isCategory) {
2389
                $categoryInfo = self::getCategoryByTitle($data['category']);
2390
                $categoryId = $categoryInfo['id'];
2391
2392
                if (!empty($categoryInfo)) {
2393
                    // Update
2394
                    self::update_category(
2395
                        $categoryId,
2396
                        $data['category'],
2397
                        $data['description'],
2398
                        $data['doc_state'],
2399
                        $data['work_state'],
2400
                        $data['calendar_state'],
2401
                        $data['announcements_state'],
2402
                        $data['forum_state'],
2403
                        $data['wiki_state'],
2404
                        $data['chat_state'],
2405
                        $data['self_reg_allowed'],
2406
                        $data['self_unreg_allowed'],
2407
                        $data['max_student'],
2408
                        $data['groups_per_user']
2409
                    );
2410
                    $data['category_id'] = $categoryId;
2411
                    $result['updated']['category'][] = $data;
2412 View Code Duplication
                } else {
2413
2414
                    // Add
2415
                    $categoryId = self::create_category(
2416
                        $data['category'],
2417
                        $data['description'],
2418
                        $data['doc_state'],
2419
                        $data['work_state'],
2420
                        $data['calendar_state'],
2421
                        $data['announcements_state'],
2422
                        $data['forum_state'],
2423
                        $data['wiki_state'],
2424
                        $data['chat_state'],
2425
                        $data['self_reg_allowed'],
2426
                        $data['self_unreg_allowed'],
2427
                        $data['max_student'],
2428
                        $data['groups_per_user']
2429
                    );
2430
2431
                    if ($categoryId) {
2432
                        $data['category_id'] = $categoryId;
2433
                        $result['added']['category'][] = $data;
2434
                    }
2435
                }
2436
                $elementsFound['categories'][] = $categoryId;
2437
            } else {
2438
                $groupInfo = self::getGroupByName($data['group']);
2439
                $categoryInfo = self::getCategoryByTitle($data['category']);
2440
                $categoryId = null;
2441
                if (!empty($categoryInfo)) {
2442
                    $categoryId = $categoryInfo['id'];
2443
                } else {
2444
                    if (!empty($groupCategories) && isset($groupCategories[0])) {
2445
                        $defaultGroupCategory = $groupCategories[0];
2446
                        $categoryId = $defaultGroupCategory['id'];
2447
                    }
2448
                }
2449
2450
                if (empty($groupInfo)) {
2451
2452
                    // Add
2453
                    $groupId = self::create_group(
2454
                        $data['group'],
2455
                        $categoryId,
2456
                        null,
2457
                        $data['max_student']
2458
                    );
2459
2460 View Code Duplication
                    if ($groupId) {
2461
                        self::set_group_properties(
2462
                            $groupId,
2463
                            $data['group'],
2464
                            $data['description'],
2465
                            $data['max_student'],
2466
                            $data['doc_state'],
2467
                            $data['work_state'],
2468
                            $data['calendar_state'],
2469
                            $data['announcements_state'],
2470
                            $data['forum_state'],
2471
                            $data['wiki_state'],
2472
                            $data['chat_state'],
2473
                            $data['self_reg_allowed'],
2474
                            $data['self_unreg_allowed'],
2475
                            $categoryId
2476
                        );
2477
                        $data['group_id'] = $groupId;
2478
                        $result['added']['group'][] = $data;
2479
                    }
2480
                    $groupInfo = self::get_group_properties($groupId, true);
2481
                } else {
2482
                    // Update
2483
                    $groupId = $groupInfo['id'];
2484
                    self::set_group_properties(
2485
                        $groupId,
2486
                        $data['group'],
2487
                        $data['description'],
2488
                        $data['max_student'],
2489
                        $data['doc_state'],
2490
                        $data['work_state'],
2491
                        $data['calendar_state'],
2492
                        $data['announcements_state'],
2493
                        $data['forum_state'],
2494
                        $data['wiki_state'],
2495
                        $data['chat_state'],
2496
                        $data['self_reg_allowed'],
2497
                        $data['self_unreg_allowed'],
2498
                        $categoryId
2499
                    );
2500
2501
                    $data['group_id'] = $groupId;
2502
                    $result['updated']['group'][] = $data;
2503
                    $groupInfo = self::get_group_properties($groupId);
2504
                }
2505
2506
2507
2508
                $students = isset($data['students']) ? explode(',', $data['students']) : [];
2509 View Code Duplication
                if (!empty($students)) {
2510
                    $studentUserIdList = array();
2511
                    foreach ($students as $student) {
2512
                        $userInfo = api_get_user_info_from_username($student);
2513
2514
                        if (!$userInfo) {
2515
                            continue;
2516
                        }
2517
2518
                        if (
2519
                            !CourseManager::is_user_subscribed_in_course(
2520
                                $userInfo['user_id'],
2521
                                $courseCode,
2522
                                !empty($sessionId),
2523
                                $sessionId
2524
                            )
2525
                        ) {
2526
                            Display::addFlash(
2527
                                Display::return_message(
2528
                                    sprintf(get_lang('StudentXIsNotSubscribedToCourse'), $userInfo['complete_name']),
2529
                                    'warning'
2530
                                )
2531
                            );
2532
2533
                            continue;
2534
                        }
2535
2536
                        $studentUserIdList[] = $userInfo['user_id'];
2537
                    }
2538
                    self::subscribe_users($studentUserIdList, $groupInfo);
0 ignored issues
show
Bug introduced by
It seems like $groupInfo can also be of type null; however, GroupManager::subscribe_users() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
2539
                }
2540
2541
                $tutors = isset($data['tutors']) ? explode(',', $data['tutors']) : [];
2542 View Code Duplication
                if (!empty($tutors)) {
2543
                    $tutorIdList = array();
2544
                    foreach ($tutors as $tutor) {
2545
                        $userInfo = api_get_user_info_from_username($tutor);
2546
2547
                        if (!$userInfo) {
2548
                            continue;
2549
                        }
2550
2551
                        if (
2552
                            !CourseManager::is_user_subscribed_in_course(
2553
                                $userInfo['user_id'],
2554
                                $courseCode,
2555
                                !empty($sessionId),
2556
                                $sessionId
2557
                            )
2558
                        ) {
2559
                            Display::addFlash(
2560
                                Display::return_message(
2561
                                    sprintf(get_lang('TutorXIsNotSubscribedToCourse'), $userInfo['complete_name']),
2562
                                    'warning'
2563
                                )
2564
                            );
2565
2566
                            continue;
2567
                        }
2568
2569
                        $tutorIdList[] = $userInfo['user_id'];
2570
                    }
2571
                    self::subscribe_tutors($tutorIdList, $groupInfo);
0 ignored issues
show
Bug introduced by
It seems like $groupInfo can also be of type null; however, GroupManager::subscribe_tutors() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
2572
                }
2573
2574
                $elementsFound['groups'][] = $groupId;
2575
            }
2576
        }
2577
2578
        if ($deleteNotInArray) {
2579
            // Check categories
2580
            $categories = self::get_categories();
2581
            foreach ($categories as $category) {
2582
                if (!in_array($category['id'], $elementsFound['categories'])) {
2583
                    self::delete_category($category['id']);
2584
                    $category['category'] = $category['title'];
2585
                    $result['deleted']['category'][] = $category;
2586
                }
2587
            }
2588
2589
            $groups = self::get_groups();
2590
            foreach ($groups as $group) {
2591
                if (!in_array($group['iid'], $elementsFound['groups'])) {
2592
                    self::delete_groups($group);
2593
                    $group['group'] = $group['name'];
2594
                    $result['deleted']['group'][] = $group;
2595
                }
2596
            }
2597
        }
2598
2599
        return $result;
2600
    }
2601
2602
    /**
2603
     * Export all categories/group from a course to an array.
2604
     * This function works only in a context of a course.
2605
     * @param int $groupId
2606
     * @param bool $loadUsers
2607
     * @return array
2608
     */
2609
    public static function exportCategoriesAndGroupsToArray($groupId = null, $loadUsers = false)
2610
    {
2611
        $data = array();
2612
        $data[] = array(
2613
            'category',
2614
            'group',
2615
            'description',
2616
            'announcements_state',
2617
            'calendar_state',
2618
            'chat_state',
2619
            'doc_state',
2620
            'forum_state',
2621
            'work_state',
2622
            'wiki_state',
2623
            'max_student',
2624
            'self_reg_allowed',
2625
            'self_unreg_allowed',
2626
            'groups_per_user'
2627
        );
2628
2629
        $count = 1;
2630
2631
        if ($loadUsers) {
2632
            $data[0][] = 'students';
2633
            $data[0][] = 'tutors';
2634
        }
2635
2636
        if ($loadUsers == false) {
2637
            $categories = self::get_categories();
2638
2639
            foreach ($categories as $categoryInfo) {
2640
                $data[$count] = array(
2641
                    $categoryInfo['title'],
2642
                    null,
2643
                    $categoryInfo['description'],
2644
                    $categoryInfo['announcements_state'],
2645
                    $categoryInfo['calendar_state'],
2646
                    $categoryInfo['chat_state'],
2647
                    $categoryInfo['doc_state'],
2648
                    $categoryInfo['forum_state'],
2649
                    $categoryInfo['work_state'],
2650
                    $categoryInfo['wiki_state'],
2651
                    $categoryInfo['max_student'],
2652
                    $categoryInfo['self_reg_allowed'],
2653
                    $categoryInfo['self_unreg_allowed'],
2654
                    $categoryInfo['groups_per_user']
2655
                );
2656
                $count++;
2657
            }
2658
        }
2659
2660
        $groups = self::get_group_list();
2661
2662
        foreach ($groups as $groupInfo) {
2663
            $categoryTitle = null;
2664
            $categoryInfo = self::get_category($groupInfo['category_id']);
2665
            $groupSettings = self::get_group_properties($groupInfo['id']);
2666
            if (!empty($categoryInfo)) {
2667
                $categoryTitle = $categoryInfo['title'];
2668
            }
2669
2670
            $users = self::getStudents($groupInfo['iid']);
2671
            $userList = array();
2672
            foreach ($users as $user) {
2673
                $user = api_get_user_info($user['user_id']);
2674
                $userList[] = $user['username'];
2675
            }
2676
2677
            $tutors = self::getTutors($groupInfo);
2678
            $tutorList = array();
2679
            foreach ($tutors as $user) {
2680
                $user = api_get_user_info($user['user_id']);
2681
                $tutorList[] = $user['username'];
2682
            }
2683
2684
            $userListToString = null;
2685
            if (!empty($userList)) {
2686
                $userListToString = implode(',', $userList);
2687
            }
2688
2689
            $tutorListToString = null;
2690
            if (!empty($tutorList)) {
2691
                $tutorListToString = implode(',', $tutorList);
2692
            }
2693
2694
            $data[$count] = array(
2695
                $categoryTitle,
2696
                $groupSettings['name'],
2697
                $groupSettings['description'],
2698
                $groupSettings['announcements_state'],
2699
                $groupSettings['calendar_state'],
2700
                $groupSettings['chat_state'],
2701
                $groupSettings['doc_state'],
2702
                $groupSettings['forum_state'],
2703
                $groupSettings['work_state'],
2704
                $groupSettings['wiki_state'],
2705
                $groupSettings['maximum_number_of_students'],
2706
                $groupSettings['self_registration_allowed'],
2707
                $groupSettings['self_unregistration_allowed'],
2708
                null
2709
            );
2710
2711
            if ($loadUsers) {
2712
                $data[$count][] = $userListToString;
2713
                $data[$count][] = $tutorListToString;
2714
            }
2715
2716
            if (!empty($groupId)) {
2717
                if ($groupId == $groupInfo['id']) {
2718
                    break;
2719
                }
2720
            }
2721
            $count++;
2722
        }
2723
2724
        return $data;
2725
    }
2726
2727
    /**
2728
     * @param string $default
2729
     */
2730
    public static function getSettingBar($default)
2731
    {
2732
        $activeSettings = null;
2733
        $activeTutor = null;
2734
        $activeMember = null;
2735
2736
        switch ($default) {
2737
            case 'settings':
2738
                $activeSettings = 'active';
2739
                break;
2740
            case'tutor':
2741
                $activeTutor = 'active';
2742
                break;
2743
            case 'member':
2744
                $activeMember = 'active';
2745
                break;
2746
        }
2747
2748
        $url = api_get_path(WEB_CODE_PATH).'group/%s?'.api_get_cidreq();
2749
2750
        echo '
2751
            <ul class="toolbar-groups nav nav-tabs">
2752
                <li class="'.$activeSettings.'">
2753
                    <a href="'.sprintf($url, 'settings.php').'">
2754
                    '.Display::return_icon('settings.png').' '.get_lang('Settings').'
2755
                    </a>
2756
                </li>
2757
                <li class="'.$activeMember.'">
2758
                    <a href="'.sprintf($url, 'member_settings.php').'">
2759
                    '.Display::return_icon('user.png').' '.get_lang('GroupMembers').'
2760
                    </a>
2761
                </li>
2762
                <li class="'.$activeTutor.'">
2763
                    <a href="'.sprintf($url, 'tutor_settings.php').'">
2764
                    '.Display::return_icon('teacher.png').' '.get_lang('GroupTutors').'
2765
                    </a>
2766
                </li>
2767
            </ul>';
2768
    }
2769
2770
    /**
2771
     * @param int $courseId
2772
     * @param string $keyword
2773
     * @return string
2774
     */
2775
    public static function getOverview($courseId, $keyword = null)
2776
    {
2777
        $content = null;
2778
        $categories = self::get_categories();
2779
        if (!empty($categories)) {
2780
2781
            foreach ($categories as $category) {
2782
                if (api_get_setting('allow_group_categories') == 'true') {
2783
                    $content .= '<h2>'.$category['title'].'</h2>';
2784
                }
2785
                if (!empty($keyword)) {
2786
                    $groups = self::getGroupListFilterByName($keyword, $category['id'], $courseId);
2787
                } else {
2788
                    $groups = self::get_group_list($category['id']);
2789
                }
2790
2791
                if (empty($groups)) {
2792
                    $groups = self::get_group_list();
2793
                }
2794
2795
                $content .= '<ul>';
2796
                if (!empty($groups)) {
2797
                    foreach ($groups as $group) {
2798
                        $content .= '<li>';
2799
                        $content .= Display::tag('h3', Security::remove_XSS($group['name']));
2800
                        $users = self::getTutors($group);
2801 View Code Duplication
                        if (!empty($users)) {
2802
                            $content .= '<ul>';
2803
                            $content .= "<li>".Display::tag('h4', get_lang('Tutors'))."</li><ul>";
2804
                            foreach ($users as $user) {
2805
                                $user_info = api_get_user_info($user['user_id']);
2806
                                $content .= '<li title="'.$user_info['username'].'">'.
2807
                                    $user_info['complete_name_with_username'].
2808
                                '</li>';
2809
                            }
2810
                            $content .= '</ul>';
2811
                            $content .= '</ul>';
2812
                        }
2813
2814
                        $users = self::getStudents($group['iid']);
2815 View Code Duplication
                        if (!empty($users)) {
2816
                            $content .= '<ul>';
2817
                            $content .= "<li>".Display::tag('h4', get_lang('Students'))."</li><ul>";
2818
                            foreach ($users as $user) {
2819
                                $user_info = api_get_user_info($user['user_id']);
2820
                                $content .= '<li title="'.$user_info['username'].'">'.
2821
                                    $user_info['complete_name_with_username'].
2822
                                    '</li>';
2823
                            }
2824
                            $content .= '</ul>';
2825
                            $content .= '</ul>';
2826
                        }
2827
                        $content .= '</li>';
2828
                    }
2829
                }
2830
                $content .= '</ul>';
2831
            }
2832
        }
2833
2834
        return $content;
2835
    }
2836
2837
    /**
2838
     * Returns the search form
2839
     * @return string
2840
     */
2841 View Code Duplication
    public static function getSearchForm()
2842
    {
2843
        $url = api_get_path(WEB_CODE_PATH).'group/group_overview.php?'.api_get_cidreq();
2844
        $form = new FormValidator(
2845
            'search_groups',
2846
            'get',
2847
            $url,
2848
            null,
2849
            array('class' => 'form-search'),
2850
            FormValidator::LAYOUT_INLINE
2851
        );
2852
        $form->addElement('text', 'keyword');
2853
        $form->addButtonSearch();
2854
        return $form->toHtml();
2855
    }
2856
2857
    /**
2858
     * @param int $groupId
2859
     * @param int $status
2860
     */
2861
    public static function setStatus($groupId, $status)
2862
    {
2863
        $groupInfo = self::get_group_properties($groupId);
2864
2865
        $courseId = api_get_course_int_id();
2866
        if (!empty($groupInfo)) {
2867
            $table = Database::get_course_table(TABLE_GROUP);
2868
            $params = array(
2869
                'status' => intval($status)
2870
            );
2871
            Database::update(
2872
                $table,
2873
                $params,
2874
                array('c_id = ? AND id = ?' => array($courseId, $groupId))
2875
            );
2876
        }
2877
    }
2878
2879
    /**
2880
     * @param int $groupId
2881
     */
2882
    public static function setVisible($groupId)
2883
    {
2884
        self::setStatus($groupId, 1);
2885
    }
2886
2887
    /**
2888
     * @param int $groupId
2889
     */
2890
    public static function setInvisible($groupId)
2891
    {
2892
        self::setStatus($groupId, 0);
2893
    }
2894
}
2895