Passed
Push — 1.10.x ( 80a1f9...d69c76 )
by
unknown
305:03 queued 255:46
created

GroupManager::is_subscribed()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 18
Code Lines 13

Duplication

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

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

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

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
790
     * @param int $groups_per_user
791
     */
792
    public static function create_category(
793
        $title,
794
        $description,
795
        $doc_state,
796
        $work_state,
797
        $calendar_state,
798
        $announcements_state,
799
        $forum_state,
800
        $wiki_state,
801
        $chat_state = 1,
802
        $self_registration_allowed = 0,
803
        $self_unregistration_allowed = 0,
804
        $maximum_number_of_students = 8,
805
        $groups_per_user = 0
806
    ) {
807
        if (empty($title)) {
808
            return false;
809
        }
810
        $table_group_category = Database :: get_course_table(TABLE_GROUP_CATEGORY);
811
        $course_id = api_get_course_int_id();
812
813
        $sql = "SELECT MAX(display_order)+1 as new_order
814
                FROM $table_group_category
815
                WHERE c_id = $course_id ";
816
        $res = Database::query($sql);
817
        $obj = Database::fetch_object($res);
818
        if (!isset ($obj->new_order)) {
819
            $obj->new_order = 1;
820
        }
821
822
        $params = [
823
            'c_id' => $course_id,
824
            'title' => $title,
825
            'display_order' => $obj->new_order,
826
            'description' => $description,
827
            'doc_state' => $doc_state,
828
            'work_state' => $work_state,
829
            'calendar_state' => $calendar_state,
830
            'announcements_state' => $announcements_state,
831
            'forum_state' => $forum_state,
832
            'wiki_state' => $wiki_state,
833
            'chat_state' => $chat_state,
834
            'groups_per_user' => $groups_per_user,
835
            'self_reg_allowed' => $self_registration_allowed,
836
            'self_unreg_allowed' => $self_unregistration_allowed,
837
            'max_student' => $maximum_number_of_students
838
        ];
839
840
        $categoryId = Database::insert($table_group_category, $params);
841
        if ($categoryId) {
842
            $sql = "UPDATE $table_group_category SET id = iid
843
                    WHERE iid = $categoryId";
844
            Database::query($sql);
845
846
            return $categoryId;
847
        }
848
849
        return false;
850
    }
851
852
    /**
853
     * Update group category
854
     *
855
     * @param int $id
856
     * @param string $title
857
     * @param string $description
858
     * @param $doc_state
859
     * @param $work_state
860
     * @param $calendar_state
861
     * @param $announcements_state
862
     * @param $forum_state
863
     * @param $wiki_state
864
     * @param $chat_state
865
     * @param $self_registration_allowed
866
     * @param $self_unregistration_allowed
867
     * @param $maximum_number_of_students
868
     * @param $groups_per_user
869
     */
870
    public static function update_category(
871
        $id,
872
        $title,
873
        $description,
874
        $doc_state,
875
        $work_state,
876
        $calendar_state,
877
        $announcements_state,
878
        $forum_state,
879
        $wiki_state,
880
        $chat_state,
881
        $self_registration_allowed,
882
        $self_unregistration_allowed,
883
        $maximum_number_of_students,
884
        $groups_per_user
885
    ) {
886
        $table_group_category = Database::get_course_table(TABLE_GROUP_CATEGORY);
887
        $id = intval($id);
888
889
        $course_id = api_get_course_int_id();
890
891
        $sql = "UPDATE ".$table_group_category." SET
892
                    title='".Database::escape_string($title)."',
893
                    description='".Database::escape_string($description)."',
894
                    doc_state = '".Database::escape_string($doc_state)."',
895
                    work_state = '".Database::escape_string($work_state)."',
896
                    calendar_state = '".Database::escape_string($calendar_state)."',
897
                    announcements_state = '".Database::escape_string($announcements_state)."',
898
                    forum_state = '".Database::escape_string($forum_state)."',
899
                    wiki_state = '".Database::escape_string($wiki_state)."',
900
                    chat_state = '".Database::escape_string($chat_state)."',
901
                    groups_per_user   = '".Database::escape_string($groups_per_user)."',
902
                    self_reg_allowed = '".Database::escape_string($self_registration_allowed)."',
903
                    self_unreg_allowed = '".Database::escape_string($self_unregistration_allowed)."',
904
                    max_student = ".intval($maximum_number_of_students)."
905
                WHERE c_id = $course_id AND id = $id";
906
907
        Database::query($sql);
908
909
        // Updating all groups inside this category
910
        $groups = self::get_group_list($id);
911
912
        if (!empty($groups)) {
913
            foreach ($groups as $group) {
914
                GroupManager::set_group_properties(
915
                    $group['id'],
916
                    $group['name'],
917
                    $group['description'],
918
                    $maximum_number_of_students,
919
                    $doc_state,
920
                    $work_state,
921
                    $calendar_state,
922
                    $announcements_state,
923
                    $forum_state,
924
                    $wiki_state,
925
                    $chat_state,
926
                    $self_registration_allowed,
927
                    $self_unregistration_allowed,
928
                    $id
929
                );
930
            }
931
        }
932
    }
933
934
    /**
935
     * Returns the number of groups of the user with the greatest number of
936
     * subscriptions in the given category
937
     */
938
    public static function get_current_max_groups_per_user($category_id = null, $course_code = null)
939
    {
940
        $course_info = api_get_course_info ($course_code);
941
        $group_table = Database :: get_course_table(TABLE_GROUP);
942
        $group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
943
        $sql = 'SELECT COUNT(gu.group_id) AS current_max
944
                FROM '.$group_user_table.' gu, '.$group_table.' g
945
				WHERE g.c_id = '.$course_info['real_id'].'
946
				AND gu.c_id = g.c_id
947
				AND gu.group_id = g.id ';
948
        if ($category_id != null) {
949
            $category_id = intval($category_id);
950
            $sql .= ' AND g.category_id = '.$category_id;
951
        }
952
        $sql .= ' GROUP BY gu.user_id ORDER BY current_max DESC LIMIT 1';
953
        $res = Database::query($sql);
954
        $obj = Database::fetch_object($res);
955
956
        return $obj->current_max;
957
    }
958
959
    /**
960
     * Swaps the display-order of two categories
961
     * @param int $id1 The id of the first category
962
     * @param int $id2 The id of the second category
963
     */
964
    public static function swap_category_order($id1, $id2)
965
    {
966
        $table_group_cat = Database :: get_course_table(TABLE_GROUP_CATEGORY);
967
        $id1 = intval($id1);
968
        $id2 = intval($id2);
969
        $course_id = api_get_course_int_id();
970
971
        $sql = "SELECT id,display_order FROM $table_group_cat
972
                WHERE id IN ($id1,$id2) AND c_id = $course_id ";
973
        $res = Database::query($sql);
974
        $cat1 = Database::fetch_object($res);
975
        $cat2 = Database::fetch_object($res);
976
        if ($cat1 && $cat2) {
977
            $sql = "UPDATE $table_group_cat SET display_order=$cat2->display_order
978
                WHERE id = $cat1->id AND c_id = $course_id ";
979
            Database::query($sql);
980
981
            $sql = "UPDATE $table_group_cat SET display_order=$cat1->display_order
982
                    WHERE id = $cat2->id AND c_id = $course_id ";
983
            Database::query($sql);
984
        }
985
    }
986
987
    /**
988
     * Get all users from a given group
989
     * @param int $group_id The group
990
     * @param bool $load_extra_info
991
     * @param int $start
992
     * @param int $limit
993
     * @param bool $getCount
994
     * @param int $courseId
995
     * @return array list of user id
996
     */
997
    public static function get_users(
998
        $group_id,
999
        $load_extra_info = false,
1000
        $start = null,
1001
        $limit = null,
1002
        $getCount = false,
1003
        $courseId = null,
1004
        $column = null,
1005
        $direction = null
1006
    ) {
1007
        $group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
1008
        $user_table = Database :: get_main_table(TABLE_MAIN_USER);
1009
1010
        $group_id = intval($group_id);
1011
1012
        if (empty($courseId)) {
1013
            $courseId = api_get_course_int_id();
1014
        } else {
1015
            $courseId = intval($courseId);
1016
        }
1017
1018
        $select = " SELECT g.user_id, firstname, lastname ";
1019
        if ($getCount) {
1020
            $select = " SELECT count(u.user_id) count";
1021
        }
1022
        $sql = "$select
1023
                FROM $group_user_table g
1024
                INNER JOIN $user_table u
1025
                ON (u.user_id = g.user_id)
1026
                WHERE c_id = $courseId AND g.group_id = $group_id";
1027
1028
        if (!empty($column) && !empty($direction)) {
1029
            $column = Database::escape_string($column, null, false);
1030
            $direction = ($direction == 'ASC' ? 'ASC' : 'DESC');
1031
            $sql .= " ORDER BY $column $direction";
1032
        }
1033
1034 View Code Duplication
        if (!empty($start) && !empty($limit)) {
1035
            $start = intval($start);
1036
            $limit = intval($limit);
1037
            $sql .= " LIMIT $start, $limit";
1038
        }
1039
        $res = Database::query($sql);
1040
        $users = array();
1041
        while ($obj = Database::fetch_object($res)) {
1042
            if ($getCount) {
1043
                return $obj->count;
1044
                break;
1045
            }
1046
            if ($load_extra_info) {
1047
                $users[] = api_get_user_info($obj->user_id);
1048
            } else {
1049
                $users[] = $obj->user_id;
1050
            }
1051
        }
1052
1053
        return $users;
1054
    }
1055
1056
    /**
1057
     * @param int $group_id
1058
     * @return array
1059
     */
1060
    public static function getStudentsAndTutors($group_id)
1061
    {
1062
        $group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
1063
        $tutor_user_table = Database :: get_course_table(TABLE_GROUP_TUTOR);
1064
        $course_id = api_get_course_int_id();
1065
        $group_id = intval($group_id);
1066
        $sql = "SELECT user_id FROM $group_user_table
1067
                WHERE c_id = $course_id AND group_id = $group_id";
1068
        $res = Database::query($sql);
1069
        $users = array();
1070
1071
        while ($obj = Database::fetch_object($res)) {
1072
            $users[] = api_get_user_info($obj->user_id);
1073
        }
1074
1075
        $sql = "SELECT user_id FROM $tutor_user_table
1076
                WHERE c_id = $course_id AND group_id = $group_id";
1077
        $res = Database::query($sql);
1078
        while ($obj = Database::fetch_object($res)) {
1079
            $users[] = api_get_user_info($obj->user_id);
1080
        }
1081
        return $users;
1082
    }
1083
1084
    /**
1085
     * Get only tutors from a group
1086
     * @param int $group_id
1087
     * @return array
1088
     */
1089 View Code Duplication
    public static function getTutors($group_id)
1090
    {
1091
        $tutor_user_table = Database :: get_course_table(TABLE_GROUP_TUTOR);
1092
        $course_id = api_get_course_int_id();
1093
        $group_id = intval($group_id);
1094
1095
        $sql = "SELECT user_id FROM $tutor_user_table
1096
                WHERE c_id = $course_id AND group_id = $group_id";
1097
        $res = Database::query($sql);
1098
1099
        $users = array();
1100
        while ($obj = Database::fetch_object($res)) {
1101
            $users[] = api_get_user_info($obj->user_id);
1102
        }
1103
        return $users;
1104
    }
1105
1106
    /**
1107
     * Get only students from a group (not tutors)
1108
     * @param int $group_id
1109
     * @return array
1110
     */
1111 View Code Duplication
    public static function getStudents($group_id)
1112
    {
1113
        $group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
1114
        $course_id = api_get_course_int_id();
1115
        $group_id = intval($group_id);
1116
        $sql = "SELECT user_id FROM $group_user_table
1117
                WHERE c_id = $course_id AND group_id = $group_id";
1118
        $res = Database::query($sql);
1119
        $users = array();
1120
1121
        while ($obj = Database::fetch_object($res)) {
1122
            $users[] = api_get_user_info($obj->user_id);
1123
        }
1124
        return $users;
1125
    }
1126
1127
    /**
1128
     * Returns users belonging to any of the group
1129
     *
1130
     * @param array $groups list of group ids
1131
     * @return array list of user ids
1132
     */
1133
    public static function get_groups_users($groups = array())
1134
    {
1135
        $result = array();
1136
        $tbl_group_user = Database::get_course_table(TABLE_GROUP_USER);
1137
        $course_id = api_get_course_int_id();
1138
1139
        $groups = array_map('intval', $groups);
1140
        // protect individual elements with surrounding quotes
1141
        $groups = implode(', ', $groups);
1142
        $sql = "SELECT DISTINCT user_id
1143
                FROM $tbl_group_user gu
1144
                WHERE c_id = $course_id AND gu.group_id IN ($groups)";
1145
        $rs = Database::query($sql);
1146
        while ($row = Database::fetch_array($rs)) {
1147
            $result[] = $row['user_id'];
1148
        }
1149
        return $result;
1150
    }
1151
1152
    /**
1153
     * Fill the groups with students.
1154
     * The algorithm takes care to first fill the groups with the least # of users.
1155
     * Analysis
1156
     * There was a problem with the "ALL" setting.
1157
     * When max # of groups is set to all, the value is sometimes NULL and sometimes ALL
1158
     * and in both cased the query does not work as expected.
1159
     * Stupid solution (currently implemented: set ALL to a big number (INFINITE) and things are solved :)
1160
     * Better solution: that's up to you.
1161
     *
1162
     * Note
1163
     * Throughout Dokeos there is some confusion about "course id" and "course code"
1164
     * The code is e.g. TEST101, but sometimes a variable that is called courseID also contains a course code string.
1165
     * However, there is also a integer course_id that uniquely identifies the course.
1166
     * ywarnier:> Now the course_id has been removed (25/1/2005)
1167
     * The databases are als very inconsistent in this.
1168
     *
1169
     * @author Chrisptophe Gesche <[email protected]>,
1170
     *         Hugues Peeters     <[email protected]> - original version
1171
     * @author Roan Embrechts - virtual course support, code cleaning
1172
     * @author Bart Mollet - code cleaning, use other GroupManager-functions
1173
     * @return void
1174
     */
1175
    public static function fill_groups($group_ids)
1176
    {
1177
        $_course = api_get_course_info();
1178
1179
        $group_ids = is_array($group_ids) ? $group_ids : array ($group_ids);
1180
        $group_ids = array_map('intval', $group_ids);
1181
1182 View Code Duplication
        if (api_is_course_coach()) {
1183
            for ($i=0 ; $i< count($group_ids) ; $i++) {
1184
                if (!api_is_element_in_the_session(TOOL_GROUP, $group_ids[$i])){
1185
                    array_splice($group_ids,$i,1);
1186
                    $i--;
1187
                }
1188
            }
1189
            if (count($group_ids)==0) {
1190
                return false;
1191
            }
1192
        }
1193
1194
        $category = self::get_category_from_group($group_ids[0]);
1195
        $groups_per_user = (isset($category['groups_per_user']) ? $category['groups_per_user'] : self::GROUP_PER_MEMBER_NO_LIMIT);
1196
        $group_table = Database:: get_course_table(TABLE_GROUP);
1197
        $group_user_table = Database:: get_course_table(TABLE_GROUP_USER);
1198
        $session_id = api_get_session_id();
1199
1200
        $complete_user_list = CourseManager :: get_real_and_linked_user_list($_course['code'], true, $session_id);
1201
        $number_groups_per_user = ($groups_per_user == self::GROUP_PER_MEMBER_NO_LIMIT ? self::INFINITE : $groups_per_user);
1202
1203
        /*
1204
         * Retrieve all the groups where enrollment is still allowed
1205
         * (reverse) ordered by the number of place available
1206
         */
1207
1208
        $course_id = api_get_course_int_id();
1209
        $sql = "SELECT g.id gid, g.max_student-count(ug.user_id) nbPlaces, g.max_student
1210
                FROM ".$group_table." g
1211
                LEFT JOIN  ".$group_user_table." ug ON
1212
                    g.c_id = $course_id AND ug.c_id = $course_id  AND g.id = ug.group_id
1213
                WHERE
1214
                    g.id IN (".implode(',', $group_ids).")
1215
                GROUP BY (g.id)
1216
                HAVING (nbPlaces > 0 OR g.max_student = ".self::MEMBER_PER_GROUP_NO_LIMIT.")
1217
                ORDER BY nbPlaces DESC";
1218
        $sql_result = Database::query($sql);
1219
        $group_available_place = array();
1220
        while ($group = Database::fetch_array($sql_result, 'ASSOC')) {
1221
            $group_available_place[$group['gid']] = $group['nbPlaces'];
1222
        }
1223
1224
        /*
1225
         * Retrieve course users (reverse) ordered by the number
1226
         * of group they are already enrolled
1227
         */
1228
        for ($i = 0; $i < count($complete_user_list); $i ++) {
1229
            //find # of groups the user is enrolled in
1230
            $number_of_groups = self :: user_in_number_of_groups($complete_user_list[$i]["user_id"], (isset($category['id'])?$category['id']:null));
1231
            //add # of groups to user list
1232
            $complete_user_list[$i]['number_groups_left'] = $number_groups_per_user - $number_of_groups;
1233
        }
1234
1235
        //first sort by user_id to filter out duplicates
1236
        $complete_user_list = TableSort :: sort_table($complete_user_list, 'user_id');
1237
        $complete_user_list = self :: filter_duplicates($complete_user_list, 'user_id');
1238
        $complete_user_list = self :: filter_only_students($complete_user_list);
1239
1240
        //now sort by # of group left
1241
        $complete_user_list = TableSort :: sort_table($complete_user_list, 'number_groups_left', SORT_DESC);
1242
        $userToken = array ();
1243
        foreach ($complete_user_list as $this_user) {
1244
            if ($this_user['number_groups_left'] > 0) {
1245
                $userToken[$this_user['user_id']] = $this_user['number_groups_left'];
1246
            }
1247
        }
1248
1249
        $changed = true;
1250
        while ($changed) {
1251
            $changed = false;
1252
            reset($group_available_place);
1253
            arsort($group_available_place);
1254
            reset($userToken);
1255
            arsort($userToken);
1256
1257
            foreach ($group_available_place as $group_id => $place) {
1258
                foreach ($userToken as $user_id => $places) {
1259
                    if (self :: can_user_subscribe($user_id, $group_id)) {
1260
                        self :: subscribe_users($user_id, $group_id);
1261
                        $group_available_place[$group_id]--;
1262
                        unset($userToken[$user_id]);
1263
                        $changed = true;
1264
                        break;
1265
                    }
1266
                }
1267
                if ($changed) {
1268
                    break;
1269
                }
1270
            }
1271
        }
1272
    }
1273
1274
    /**
1275
     * Get the number of students in a group.
1276
     * @param int $group_id
1277
     * @return int Number of students in the given group.
1278
     */
1279 View Code Duplication
    public static function number_of_students($group_id, $course_id = null)
1280
    {
1281
        $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
1282
        $group_id = intval($group_id);
1283
        if (empty($course_id)) {
1284
            $course_id = api_get_course_int_id();
1285
        } else {
1286
            $course_id = intval($course_id);
1287
        }
1288
        $sql = "SELECT  COUNT(*) AS number_of_students
1289
                FROM $table_group_user
1290
                WHERE c_id = $course_id AND group_id = $group_id";
1291
        $db_result = Database::query($sql);
1292
        $db_object = Database::fetch_object($db_result);
1293
        return $db_object->number_of_students;
1294
    }
1295
1296
    /**
1297
     * Maximum number of students in a group
1298
     * @param int $group_id
1299
     * @return int Maximum number of students in the given group.
1300
     */
1301
    public static function maximum_number_of_students($group_id)
1302
    {
1303
        $table_group = Database :: get_course_table(TABLE_GROUP);
1304
        $group_id = intval($group_id);
1305
        $course_id = api_get_course_int_id();
1306
        $db_result = Database::query("SELECT max_student FROM $table_group WHERE c_id = $course_id AND id = $group_id");
1307
        $db_object = Database::fetch_object($db_result);
1308
        if ($db_object->max_student == 0) {
1309
            return self::INFINITE;
1310
        }
1311
        return $db_object->max_student;
1312
    }
1313
1314
    /**
1315
     * Number of groups of a user
1316
     * @param int $user_id
1317
     * @return int The number of groups the user is subscribed in.
1318
     */
1319
    public static function user_in_number_of_groups($user_id, $cat_id = null)
1320
    {
1321
        $table_group_user = Database:: get_course_table(TABLE_GROUP_USER);
1322
        $table_group = Database:: get_course_table(TABLE_GROUP);
1323
        $user_id = intval($user_id);
1324
        $cat_id = intval($cat_id);
1325
1326
        $course_id = api_get_course_int_id();
1327
        $cat_condition = '';
1328
        if (!empty($cat_id)) {
1329
            $cat_condition = " AND g.category_id =  $cat_id ";
1330
        }
1331
1332
        $sql = "SELECT  COUNT(*) AS number_of_groups
1333
                FROM $table_group_user gu, $table_group g
1334
                WHERE
1335
                    gu.c_id     = $course_id AND
1336
                    g.c_id         = $course_id AND
1337
                    gu.user_id     = $user_id AND
1338
                    g.id         = gu.group_id  $cat_condition";
1339
        $db_result = Database::query($sql);
1340
        $db_object = Database::fetch_object($db_result);
1341
1342
        return $db_object->number_of_groups;
1343
    }
1344
1345
    /**
1346
     * Is sef-registration allowed?
1347
     * @param int $user_id
1348
     * @param int $group_id
1349
     * @return bool TRUE if self-registration is allowed in the given group.
1350
     */
1351
    public static function is_self_registration_allowed($user_id, $group_id)
1352
    {
1353
        $course_id = api_get_course_int_id();
1354
        if (!$user_id > 0) {
1355
            return false;
1356
        }
1357
        $table_group = Database :: get_course_table(TABLE_GROUP);
1358
        $group_id = intval($group_id);
1359
        if (isset($group_id)) {
1360
            $sql = "SELECT  self_registration_allowed
1361
                    FROM $table_group
1362
                    WHERE c_id = $course_id AND id = $group_id";
1363
            $db_result = Database::query($sql);
1364
            $db_object = Database::fetch_object($db_result);
1365
1366
            return $db_object->self_registration_allowed == 1 && self :: can_user_subscribe($user_id, $group_id);
1367
        } else {
1368
            return false;
1369
        }
1370
    }
1371
1372
    /**
1373
     * Is sef-unregistration allowed?
1374
     * @param int $user_id
1375
     * @param int $group_id
1376
     * @return bool TRUE if self-unregistration is allowed in the given group.
1377
     */
1378
    public static function is_self_unregistration_allowed($user_id, $group_id)
1379
    {
1380
        if (!$user_id > 0) {
1381
            return false;
1382
        }
1383
        $table_group = Database :: get_course_table(TABLE_GROUP);
1384
        $group_id = intval($group_id);
1385
        $course_id = api_get_course_int_id();
1386
        $db_result = Database::query(
1387
            'SELECT  self_unregistration_allowed
1388
             FROM '.$table_group.'
1389
             WHERE c_id = '.$course_id.' AND id = '.$group_id
1390
        );
1391
        $db_object = Database::fetch_object($db_result);
1392
1393
        return $db_object->self_unregistration_allowed == 1 && self :: can_user_unsubscribe($user_id, $group_id);
1394
    }
1395
1396
    /**
1397
     * Is user subscribed in group?
1398
     * @param int $user_id
1399
     * @param int $group_id
1400
     * @return bool TRUE if given user is subscribed in given group
1401
     */
1402
    public static function is_subscribed($user_id, $group_id)
1403
    {
1404
        if (empty($user_id) or empty($group_id)) {
1405
            return false;
1406
        }
1407
        $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
1408
        $group_id = intval($group_id);
1409
        $user_id = intval($user_id);
1410
        $course_id = api_get_course_int_id();
1411
        $sql = 'SELECT 1 FROM '.$table_group_user.'
1412
                WHERE
1413
                    c_id = '.$course_id.' AND
1414
                    group_id = '.$group_id.' AND
1415
                    user_id = '.$user_id;
1416
        $result = Database::query($sql);
1417
1418
        return Database::num_rows($result) > 0;
1419
    }
1420
1421
    /**
1422
     * Can a user subscribe to a specified group in a course
1423
     * @param int $user_id
1424
     * @param int $group_id
1425
     * @param bool $checkMaxNumberStudents
1426
     *
1427
     * @return bool TRUE if given user  can be subscribed in given group
1428
     */
1429
    public static function can_user_subscribe($user_id, $group_id, $checkMaxNumberStudents = true)
1430
    {
1431
        if ($checkMaxNumberStudents) {
1432
            $category = self:: get_category_from_group($group_id);
1433
            if ($category) {
1434
                if ($category['groups_per_user'] == self::GROUP_PER_MEMBER_NO_LIMIT) {
1435
                    $category['groups_per_user'] = self::INFINITE;
1436
                }
1437
                $result = self:: user_in_number_of_groups($user_id, $category['id'] ) < $category['groups_per_user'];
1438
                if ($result == false) {
1439
                    return false;
1440
                }
1441
            }
1442
1443
            $result = self:: number_of_students($group_id) < self:: maximum_number_of_students($group_id);
1444
1445
            if ($result == false) {
1446
                return false;
1447
            }
1448
        }
1449
1450
        $result = self :: is_tutor_of_group($user_id, $group_id);
1451
        if ($result) {
1452
            return false;
1453
        }
1454
1455
        $result = self :: is_subscribed($user_id, $group_id);
1456
        if ($result) {
1457
            return false;
1458
        }
1459
1460
        return true;
1461
    }
1462
1463
    /**
1464
     * Can a user unsubscribe to a specified group in a course
1465
     * @param int $user_id
1466
     * @param int $group_id
1467
     * @return bool TRUE if given user  can be unsubscribed from given group
1468
     * @internal for now, same as GroupManager::is_subscribed($user_id,$group_id)
1469
     */
1470
    public static function can_user_unsubscribe($user_id, $group_id)
1471
    {
1472
        $result = self :: is_subscribed($user_id, $group_id);
1473
1474
        return $result;
1475
    }
1476
1477
    /**
1478
     * Get all subscribed users (members) from a group
1479
     * @param int $group_id
1480
     * @return array An array with information of all users from the given group.
1481
     *               (user_id, firstname, lastname, email)
1482
     */
1483
    public static function get_subscribed_users($group_id)
1484
    {
1485
        $table_user = Database :: get_main_table(TABLE_MAIN_USER);
1486
        $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
1487
        $order_clause = api_sort_by_first_name() ? ' ORDER BY u.firstname, u.lastname' : ' ORDER BY u.lastname, u.firstname';
1488
        $orderListByOfficialCode = api_get_setting('order_user_list_by_official_code');
1489
        if ($orderListByOfficialCode === 'true') {
1490
            $order_clause = " ORDER BY u.official_code, u.firstname, u.lastname";
1491
        }
1492
1493
        if (empty($group_id)) {
1494
            return array();
1495
        }
1496
        $group_id = intval($group_id);
1497
        $course_id = api_get_course_int_id();
1498
1499
        $sql = "SELECT ug.id, u.user_id, u.lastname, u.firstname, u.email, u.username
1500
                FROM  $table_user u INNER JOIN $table_group_user ug
1501
                ON (ug.user_id = u.user_id)
1502
                WHERE ug.c_id = $course_id AND
1503
                      ug.group_id = $group_id
1504
                $order_clause";
1505
        $db_result = Database::query($sql);
1506
        $users = array();
1507
        while ($user = Database::fetch_object($db_result)) {
1508
            $users[$user->user_id] = array(
1509
                'user_id'   => $user->user_id,
1510
                'firstname' => $user->firstname,
1511
                'lastname'  => $user->lastname,
1512
                'email'     => $user->email,
1513
                'username'  => $user->username
1514
            );
1515
        }
1516
1517
        return $users;
1518
    }
1519
1520
    /**
1521
     * @author Patrick Cool <[email protected]>, Ghent University
1522
     * Get all subscribed tutors of a group
1523
     * @param int $group_id
1524
     * @return array An array with information of all users from the given group.
1525
     *               (user_id, firstname, lastname, email)
1526
     */
1527
    public static function get_subscribed_tutors($group_id, $id_only = false)
1528
    {
1529
        $table_user = Database :: get_main_table(TABLE_MAIN_USER);
1530
        $table_group_tutor = Database :: get_course_table(TABLE_GROUP_TUTOR);
1531
        $order_clause = api_sort_by_first_name() ? ' ORDER BY u.firstname, u.lastname' : ' ORDER BY u.lastname, u.firstname';
1532
1533
        $orderListByOfficialCode = api_get_setting('order_user_list_by_official_code');
1534
        if ($orderListByOfficialCode === 'true') {
1535
            $order_clause = " ORDER BY u.official_code, u.firstname, u.lastname";
1536
        }
1537
1538
        $group_id = intval($group_id);
1539
        $course_id = api_get_course_int_id();
1540
1541
        $sql = "SELECT tg.id, u.user_id, u.lastname, u.firstname, u.email
1542
                FROM ".$table_user." u, ".$table_group_tutor." tg
1543
                WHERE
1544
                    tg.c_id = $course_id AND
1545
                    tg.group_id='".$group_id."' AND
1546
                    tg.user_id=u.user_id".$order_clause;
1547
        $db_result = Database::query($sql);
1548
        $users = array ();
1549
        while ($user = Database::fetch_object($db_result)) {
1550
            if (!$id_only) {
1551
                $member['user_id'] = $user->user_id;
1552
                $member['firstname'] = $user->firstname;
1553
                $member['lastname'] = $user->lastname;
1554
                $member['email'] = $user->email;
1555
                $users[] = $member;
1556
            } else {
1557
                $users[] = $user->user_id;
1558
            }
1559
        }
1560
1561
        return $users;
1562
    }
1563
1564
    /**
1565
     * Subscribe user(s) to a specified group in current course (as a student)
1566
     * @param mixed $user_ids Can be an array with user-id's or a single user-id
1567
     * @param int $group_id
1568
     * @param int $course_id
1569
     * @return bool TRUE if successful
1570
     */
1571
    public static function subscribe_users($user_ids, $group_id, $course_id = null)
1572
    {
1573
        $user_ids = is_array($user_ids) ? $user_ids : array($user_ids);
1574
        $course_id = isset($course_id) && !empty($course_id) ? intval($course_id) : api_get_course_int_id();
1575
        $group_id = intval($group_id);
1576
1577
        $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
1578
        if (!empty($user_ids)) {
1579 View Code Duplication
            foreach ($user_ids as $user_id) {
1580
                if (self::can_user_subscribe($user_id, $group_id)) {
1581
                    $user_id = intval($user_id);
1582
                    $sql = "INSERT INTO ".$table_group_user." (c_id, user_id, group_id)
1583
                            VALUES ('$course_id', '".$user_id."', '".$group_id."')";
1584
                    Database::query($sql);
1585
                }
1586
            }
1587
        }
1588
1589
        return true;
1590
    }
1591
1592
    /**
1593
     * Subscribe tutor(s) to a specified group in current course
1594
     * @param mixed $user_ids Can be an array with user-id's or a single user-id
1595
     * @param int $group_id
1596
     * @param int $course_id
1597
     *
1598
     * @author Patrick Cool <[email protected]>, Ghent University
1599
     * @see subscribe_users. This function is almost an exact copy of that function.
1600
     * @return bool TRUE if successful
1601
     */
1602
    public static function subscribe_tutors($user_ids, $group_id, $course_id = null)
1603
    {
1604
        $user_ids = is_array($user_ids) ? $user_ids : array($user_ids);
1605
        $result = true;
1606
        $course_id = isset($course_id) && !empty($course_id) ? intval($course_id) : api_get_course_int_id();
1607
        $table_group_tutor = Database :: get_course_table(TABLE_GROUP_TUTOR);
1608
        $group_id = intval($group_id);
1609
1610 View Code Duplication
        foreach ($user_ids as $user_id) {
1611
            $user_id = intval($user_id);
1612
            if (self::can_user_subscribe($user_id, $group_id, false)) {
1613
                $sql = "INSERT INTO " . $table_group_tutor . " (c_id, user_id, group_id)
1614
                        VALUES ('$course_id', '" . $user_id . "', '" . $group_id . "')";
1615
                $result &= Database::query($sql);
1616
            }
1617
        }
1618
1619
        return $result;
1620
    }
1621
1622
    /**
1623
     * Unsubscribe user(s) from a specified group in current course
1624
     * @param mixed $user_ids Can be an array with user-id's or a single user-id
1625
     * @param int $group_id
1626
     * @return bool TRUE if successful
1627
     */
1628
    public static function unsubscribe_users($user_ids, $group_id)
1629
    {
1630
        $user_ids = is_array($user_ids) ? $user_ids : array ($user_ids);
1631
        $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
1632
        $group_id = intval($group_id);
1633
        $course_id = api_get_course_int_id();
1634
        $sql = 'DELETE FROM '.$table_group_user.'
1635
                WHERE
1636
                    c_id = '.$course_id.' AND
1637
                    group_id = '.$group_id.' AND
1638
                    user_id IN ('.implode(',', $user_ids).')
1639
                ';
1640
        Database::query($sql);
1641
    }
1642
1643
    /**
1644
     * Unsubscribe all users from one or more groups
1645
     * @param mixed $group_id Can be an array with group-id's or a single group-id
0 ignored issues
show
Documentation introduced by
There is no parameter named $group_id. Did you maybe mean $group_ids?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
1646
     * @return bool TRUE if successful
1647
     */
1648
    public static function unsubscribe_all_users($group_ids)
1649
    {
1650
        $course_id = api_get_course_int_id();
1651
1652
        $group_ids = is_array($group_ids) ? $group_ids : array($group_ids);
1653
        $group_ids = array_map('intval', $group_ids);
1654
        if (count($group_ids) > 0) {
1655 View Code Duplication
            if (api_is_course_coach()) {
1656
                for ($i = 0; $i < count($group_ids); $i++) {
1657
                    if (!api_is_element_in_the_session(TOOL_GROUP, $group_ids[$i])) {
1658
                        array_splice($group_ids, $i, 1);
1659
                        $i--;
1660
                    }
1661
                }
1662
                if (count($group_ids) == 0) {
1663
                    return false;
1664
                }
1665
            }
1666
            $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
1667
            $sql = 'DELETE FROM '.$table_group_user.'
1668
                    WHERE group_id IN ('.implode(',', $group_ids).') AND c_id = '.$course_id;
1669
            $result = Database::query($sql);
1670
            return $result;
1671
        }
1672
        return true;
1673
    }
1674
1675
    /**
1676
     * Unsubscribe all tutors from one or more groups
1677
     * @param mixed $group_id Can be an array with group-id's or a single group-id
0 ignored issues
show
Documentation introduced by
There is no parameter named $group_id. Did you maybe mean $group_ids?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
1678
     * @see unsubscribe_all_users. This function is almost an exact copy of that function.
1679
     * @return bool TRUE if successful
1680
     * @author Patrick Cool <[email protected]>, Ghent University
1681
     */
1682
    public static function unsubscribe_all_tutors($group_ids)
1683
    {
1684
        $course_id = api_get_course_int_id();
1685
        $group_ids = is_array($group_ids) ? $group_ids : array($group_ids);
1686
        if (count($group_ids) > 0) {
1687
            $table_group_tutor = Database :: get_course_table(TABLE_GROUP_TUTOR);
1688
            $sql = 'DELETE FROM '.$table_group_tutor.'
1689
                    WHERE group_id IN ('.implode(',', $group_ids).') AND c_id = '.$course_id;
1690
            $result = Database::query($sql);
1691
            return $result;
1692
        }
1693
        return true;
1694
    }
1695
1696
    /**
1697
     * Is the user a tutor of this group?
1698
     * @param int $user_id the id of the user
1699
     * @param int $group_id the id of the group
1700
     * @return boolean true/false
1701
     * @todo use the function user_has_access that includes this function
1702
     * @author Patrick Cool <[email protected]>, Ghent University
1703
     */
1704
    public static function is_tutor_of_group($user_id, $group_id)
1705
    {
1706
        $table_group_tutor = Database :: get_course_table(TABLE_GROUP_TUTOR);
1707
        $user_id = intval($user_id);
1708
        $group_id = intval($group_id);
1709
        $course_id = api_get_course_int_id();
1710
1711
        $sql = "SELECT * FROM ".$table_group_tutor."
1712
                WHERE c_id = $course_id AND user_id='".$user_id."' AND group_id='".$group_id."'";
1713
        $result = Database::query($sql);
1714
        if (Database::num_rows($result) > 0) {
1715
            return true;
1716
        } else {
1717
            return false;
1718
        }
1719
    }
1720
1721
    /**
1722
     * Is the user part of this group? This can be a tutor or a normal member
1723
     * you should use this function if the access to a tool or functionality is
1724
     * restricted to the people who are actually in the group
1725
     * before you had to check if the user was
1726
     * 1. a member of the group OR
1727
     * 2. a tutor of the group. This function combines both
1728
     * @param int $user_id the id of the user
1729
     * @param int $group_id the id of the group
1730
     * @return boolean true/false
1731
     * @author Patrick Cool <[email protected]>, Ghent University
1732
     */
1733
    public static function is_user_in_group($user_id, $group_id)
1734
    {
1735
        $member = self :: is_subscribed($user_id, $group_id);
1736
        $tutor = self :: is_tutor_of_group($user_id, $group_id);
1737
        if ($member OR $tutor) {
1738
            return true;
1739
        } else {
1740
            return false;
1741
        }
1742
    }
1743
1744
    /**
1745
     * Get all group's from a given course in which a given user is unsubscribed
1746
     * @author  Patrick Cool
1747
     * @param     int  course id
1748
     * retrieve the groups for
1749
     * @param integer $user_id: the ID of the user you want to know all its
0 ignored issues
show
Documentation introduced by
There is no parameter named $user_id:. Did you maybe mean $user_id?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
1750
     * group memberships
1751
     */
1752
    public static function get_group_ids($course_id, $user_id)
1753
    {
1754
        $groups = array();
1755
        $tbl_group = Database::get_course_table(TABLE_GROUP_USER);
1756
        $tbl_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
1757
        $user_id = intval($user_id);
1758
        $course_id = intval($course_id);
1759
1760
        $sql = "SELECT group_id FROM $tbl_group
1761
                WHERE c_id = $course_id AND user_id = '$user_id'";
1762
        $groupres = Database::query($sql);
1763
1764
        if ($groupres) {
1765
            while ($myrow = Database::fetch_array($groupres)) {
1766
                $groups[] = $myrow['group_id'];
1767
            }
1768
        }
1769
1770
        //Also loading if i'm the tutor
1771
        $sql = "SELECT group_id FROM $tbl_group_tutor
1772
                WHERE c_id = $course_id AND user_id = '$user_id'";
1773
        $groupres = Database::query($sql);
1774
        if ($groupres) {
1775
            while ($myrow = Database::fetch_array($groupres)) {
1776
                $groups[] = $myrow['group_id'];
1777
            }
1778
        }
1779
        if (!empty($groups)) {
1780
            array_filter($groups);
1781
        }
1782
1783
        return $groups;
1784
    }
1785
1786
    /**
1787
     * Get a combined list of all users of the real course $course_code
1788
     *     and all users in virtual courses linked to this course $course_code
1789
     * Filter user list: remove duplicate users; plus
1790
     *     remove users that
1791
     *     - are already in the current group $group_id;
1792
     *     - do not have student status in these courses;
1793
     *     - are not appointed as tutor (group assistent) for this group;
1794
     *     - have already reached their maximum # of groups in this course.
1795
     *
1796
     * Originally to get the correct list of users a big SQL statement was used,
1797
     * but this has become more complicated now there is not just one real course but many virtual courses.
1798
     * Still, that could have worked as well.
1799
     *
1800
     * @version 1.1.3
1801
     * @author Roan Embrechts
1802
     */
1803
    public static function get_complete_list_of_users_that_can_be_added_to_group($course_code, $group_id)
1804
    {
1805
        $_course = api_get_course_info();
1806
1807
        $category = self :: get_category_from_group($group_id, $course_code);
1808
        $number_of_groups_limit = $category['groups_per_user'] == self::GROUP_PER_MEMBER_NO_LIMIT ? self::INFINITE : $category['groups_per_user'];
1809
        $real_course_code = $_course['sysCode'];
1810
        $real_course_info = api_get_course_info($real_course_code);
1811
1812
        // add real course to the list
1813
        $user_subscribed_course_list = array($real_course_info);
1814
1815
        // for all courses...
1816
        foreach ($user_subscribed_course_list as $this_course) {
1817
            $this_course_code = $this_course['code'];
1818
            $course_user_list = CourseManager :: get_user_list_from_course_code($this_course_code);
1819
            //for all users in the course
1820
            foreach ($course_user_list as $this_user) {
0 ignored issues
show
Bug introduced by
The expression $course_user_list of type array|integer is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
1821
                $user_id = $this_user['user_id'];
1822
                $loginname = $this_user['username'];
1823
                $lastname = $this_user['lastname'];
1824
                $firstname = $this_user['firstname'];
1825
                $status = $this_user['status'];
1826
                //$role =  $this_user['role'];
1827
                $isTutor = $this_user['is_tutor'];
1828
                $full_name = api_get_person_name($firstname, $lastname);
1829
                if ($lastname == "" || $firstname == '') {
1830
                    $full_name = $loginname;
1831
                }
1832
                $complete_user['user_id'] = $user_id;
1833
                $complete_user['full_name'] = $full_name;
1834
                $complete_user['firstname'] = $firstname;
1835
                $complete_user['lastname'] = $lastname;
1836
                $complete_user['status'] = $status;
1837
                $complete_user['is_tutor'] = $isTutor;
1838
                $student_number_of_groups = self :: user_in_number_of_groups($user_id, $category['id']);
1839
                //filter: only add users that have not exceeded their maximum amount of groups
1840
                if ($student_number_of_groups < $number_of_groups_limit) {
1841
                    $complete_user_list[] = $complete_user;
1842
                }
1843
            }
1844
        }
1845
1846
        if (is_array($complete_user_list)) {
1847
            //sort once, on array field "full_name"
1848
            $complete_user_list = TableSort :: sort_table($complete_user_list, "full_name");
1849
            //filter out duplicates, based on field "user_id"
1850
            $complete_user_list = self :: filter_duplicates($complete_user_list, "user_id");
1851
            $complete_user_list = self :: filter_users_already_in_group($complete_user_list, $group_id);
1852
        }
1853
1854
        return $complete_user_list;
1855
    }
1856
    /**
1857
     * Filter out duplicates in a multidimensional array
1858
     * by comparing field $compare_field.
1859
     *
1860
     * @param $user_array_in list of users (must be sorted).
1861
     * @param string $compare_field, the field to be compared
0 ignored issues
show
Documentation introduced by
There is no parameter named $compare_field,. Did you maybe mean $compare_field?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
1862
     */
1863
    public static function filter_duplicates($user_array_in, $compare_field)
1864
    {
1865
        $total_number = count($user_array_in);
1866
        $user_array_out[0] = $user_array_in[0];
1867
        $count_out = 0;
1868
        for ($count_in = 1; $count_in < $total_number; $count_in++) {
1869
            if ($user_array_in[$count_in][$compare_field] != $user_array_out[$count_out][$compare_field]) {
1870
                $count_out++;
1871
                $user_array_out[$count_out] = $user_array_in[$count_in];
1872
            }
1873
        }
1874
        return $user_array_out;
1875
    }
1876
    /**
1877
     * Filters from the array $user_array_in the users already in the group $group_id.
1878
     */
1879
    public static function filter_users_already_in_group($user_array_in, $group_id)
1880
    {
1881
        foreach ($user_array_in as $this_user) {
1882
            if (!self :: is_subscribed($this_user['user_id'], $group_id)) {
1883
                $user_array_out[] = $this_user;
1884
            }
1885
        }
1886
        return $user_array_out;
1887
    }
1888
1889
    /**
1890
     * Remove all users that are not students and all users who have tutor status
1891
     * from  the list.
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 id
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);
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, $group_id);
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['id'];
2018
        $tutors = self::get_subscribed_tutors($groupId, 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 (
2029
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_FORUM) ||
2030
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_DOCUMENTS) ||
2031
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_CALENDAR) ||
2032
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_ANNOUNCEMENT) ||
2033
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_WORK) ||
2034
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_WIKI) ||
2035
            self::user_has_access($userId, $groupId, self::GROUP_TOOL_CHAT)
2036
        ) {
2037
2038
            return true;
2039
        }
2040
2041
        if (api_is_course_coach() && $groupInfo['session_id'] == $sessionId) {
2042
            return true;
2043
        }
2044
2045
        return false;
2046
    }
2047
2048
2049
    /**
2050
     * Get all groups where a specific user is subscribed
2051
     * @param int $user_id
2052
     * @return array
2053
     */
2054
    public static function get_user_group_name($user_id)
2055
    {
2056
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
2057
        $table_group = Database::get_course_table(TABLE_GROUP);
2058
        $user_id = intval($user_id);
2059
        $course_id = api_get_course_int_id();
2060
        $sql = "SELECT name
2061
                FROM $table_group g INNER JOIN $table_group_user gu
2062
                ON (gu.group_id=g.id)
2063
                WHERE
2064
                  gu.c_id= $course_id AND
2065
                  g.c_id= $course_id AND
2066
                  gu.user_id = $user_id";
2067
        $res = Database::query($sql);
2068
        $groups = array();
2069
        while ($group = Database::fetch_array($res)) {
2070
            $groups[] .= $group['name'];
2071
        }
2072
        return $groups;
2073
    }
2074
2075
    /**
2076
     * Get all groups where a specific user is subscribed
2077
     * @param int $user_id
2078
     * @return array
2079
     */
2080
    public static function getAllGroupPerUserSubscription($user_id)
2081
    {
2082
        $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
2083
        $table_tutor_user = Database::get_course_table(TABLE_GROUP_TUTOR);
2084
        $table_group = Database::get_course_table(TABLE_GROUP);
2085
        $user_id = intval($user_id);
2086
        $course_id = api_get_course_int_id();
2087
        $sql = "SELECT DISTINCT g.*
2088
               FROM $table_group g
2089
               LEFT JOIN $table_group_user gu
2090
               ON (gu.group_id = g.id AND g.c_id = gu.c_id)
2091
               LEFT JOIN $table_tutor_user tu
2092
               ON (tu.group_id = g.id AND g.c_id = tu.c_id)
2093
               WHERE
2094
                  g.c_id = $course_id AND
2095
                  (gu.user_id = $user_id OR tu.user_id = $user_id) ";
2096
        $res = Database::query($sql);
2097
        $groups = array();
2098
        while ($group = Database::fetch_array($res, 'ASSOC')) {
2099
            $groups[] = $group;
2100
        }
2101
2102
        return $groups;
2103
    }
2104
2105
    /**
2106
     *
2107
     * See : fill_groups
2108
     *       Fill the groups with students.
2109
     *
2110
     * note : optimize fill_groups_list <--> fill_groups
2111
     * @param array $group_ids
2112
     * @return array|bool
2113
     */
2114
    public static function fill_groups_list($group_ids)
2115
    {
2116
        $group_ids = is_array($group_ids) ? $group_ids : array($group_ids);
2117
        $group_ids = array_map('intval', $group_ids);
2118
2119 View Code Duplication
        if (api_is_course_coach()) {
2120
            for ($i = 0; $i < count($group_ids); $i++) {
2121
                if (!api_is_element_in_the_session(TOOL_GROUP, $group_ids[$i])) {
2122
                    array_splice($group_ids, $i, 1);
2123
                    $i--;
2124
                }
2125
            }
2126
            if (count($group_ids) == 0) {
2127
                return false;
2128
            }
2129
        }
2130
2131
        $_course = api_get_course_info();
2132
2133
        $category = self :: get_category_from_group($group_ids[0]);
2134
        $number_groups_per_user = self::GROUP_PER_MEMBER_NO_LIMIT;
2135
        $categoryId = 0;
2136
        if ($category) {
2137
            $groups_per_user = $category['groups_per_user'];
2138
            $number_groups_per_user = ($groups_per_user == self::GROUP_PER_MEMBER_NO_LIMIT ? self::INFINITE : $groups_per_user);
2139
            $categoryId = $category['id'];
2140
        }
2141
2142
        $group_table = Database :: get_course_table(TABLE_GROUP);
2143
        $group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
2144
        $session_id = api_get_session_id();
2145
        $complete_user_list = CourseManager :: get_real_and_linked_user_list($_course['code'], true, $session_id);
2146
        $course_id = api_get_course_int_id();
2147
2148
        /*
2149
         * Retrieve all the groups where enrollment is still allowed
2150
         * (reverse) ordered by the number of place available
2151
         */
2152
        $sql = "SELECT g.id gid, count(ug.user_id) count_users, g.max_student
2153
                FROM ".$group_table." g
2154
                LEFT JOIN  ".$group_user_table." ug
2155
                ON    g.id = ug.group_id
2156
                WHERE   g.c_id = $course_id AND
2157
                        ug.c_id = $course_id AND
2158
                        g.id IN (".implode(',', $group_ids).")
2159
                GROUP BY (g.id)";
2160
2161
        $sql_result = Database::query($sql);
2162
        $group_available_place = array();
2163
        while ($group = Database::fetch_array($sql_result, 'ASSOC')) {
2164
            if (!empty($group['max_student'])) {
2165
                $places = intval($group['max_student'] - $group['count_users']);
2166
            } else {
2167
                $places = self::MEMBER_PER_GROUP_NO_LIMIT;
2168
            }
2169
            $group_available_place[$group['gid']] = $places;
2170
        }
2171
2172
        /*
2173
         * Retrieve course users (reverse) ordered by the number
2174
         * of group they are already enrolled
2175
         */
2176
        for ($i = 0; $i < count($complete_user_list); $i ++) {
2177
            // find # of groups the user is enrolled in
2178
            $number_of_groups = self:: user_in_number_of_groups(
2179
                $complete_user_list[$i]["user_id"],
2180
                $categoryId
2181
            );
2182
            // add # of groups to user list
2183
            $complete_user_list[$i]['number_groups_left'] = $number_groups_per_user - $number_of_groups;
2184
        }
2185
        //first sort by user_id to filter out duplicates
2186
        $complete_user_list = TableSort::sort_table($complete_user_list, 'user_id');
2187
        $complete_user_list = self::filter_duplicates($complete_user_list, 'user_id');
2188
        //$complete_user_list = self :: filter_only_students($complete_user_list);
2189
        //now sort by # of group left
2190
        $complete_user_list = TableSort::sort_table($complete_user_list, 'number_groups_left', SORT_DESC);
2191
2192
        return $complete_user_list;
2193
    }
2194
2195
    /**
2196
     * @param array $group_list
2197
     * @param int $category_id
2198
     *
2199
     * @return string
2200
     */
2201
    public static function process_groups($group_list, $category_id = null)
2202
    {
2203
        global $origin, $charset;
2204
        $category_id = intval($category_id);
2205
2206
        $totalRegistered = 0;
2207
        $group_data = array();
2208
        $user_info = api_get_user_info();
2209
        $session_id = api_get_session_id();
2210
        $user_id = $user_info['user_id'];
2211
2212
        $orig = isset($origin) ? $origin : null;
2213
2214
        $hideGroup = api_get_setting('hide_course_group_if_no_tools_available');
2215
2216
        foreach ($group_list as $this_group) {
2217
2218
            // Validation when belongs to a session
2219
            $session_img = api_get_session_image($this_group['session_id'], $user_info['status']);
2220
2221
            // All the tutors of this group
2222
            $tutorsids_of_group = self::get_subscribed_tutors($this_group['id'], true);
2223
            $isMember = self::is_subscribed($user_id, $this_group['id']);
2224
2225
            // Create a new table-row
2226
            $row = array();
2227
2228
            // Checkbox
2229
            if (api_is_allowed_to_edit(false, true) && count($group_list) > 1) {
2230
                $row[] = $this_group['id'];
2231
            }
2232
2233
            if (GroupManager::userHasAccessToBrowse($user_id, $this_group, $session_id)) {
2234
                // Group name
2235
                $groupNameClass = null;
2236
                if ($this_group['status'] == 0) {
2237
                    $groupNameClass = 'muted';
2238
                }
2239
2240
                $group_name = '<a class="'.$groupNameClass.'" href="group_space.php?cidReq='.api_get_course_id().'&origin='.$orig.'&gidReq='.$this_group['id'].'">'.
2241
                    Security::remove_XSS($this_group['name']).'</a> ';
2242
                if (!empty($user_id) && !empty($this_group['id_tutor']) && $user_id == $this_group['id_tutor']) {
2243
                    $group_name .= Display::label(get_lang('OneMyGroups'), 'success');
2244
                } elseif ($isMember) {
2245
                    $group_name .= Display::label(get_lang('MyGroup'), 'success');
2246
                }
2247
2248
                if (api_is_allowed_to_edit() && !empty($this_group['session_name'])) {
2249
                    $group_name .= ' ('.$this_group['session_name'].')';
2250
                }
2251
                $group_name .= $session_img;
2252
                $row[] = $group_name.'<br />'.stripslashes(trim($this_group['description']));
2253
            } else {
2254
                if ($hideGroup === 'true') {
2255
                    continue;
2256
                }
2257
                $row[] = $this_group['name'].'<br />'.stripslashes(trim($this_group['description']));
2258
            }
2259
2260
            // Tutor name
2261
            $tutor_info = null;
2262
2263
            if (count($tutorsids_of_group) > 0) {
2264
                foreach ($tutorsids_of_group as $tutor_id) {
2265
                    $tutor = api_get_user_info($tutor_id);
2266
                    $username = api_htmlentities(sprintf(get_lang('LoginX'), $tutor['username']), ENT_QUOTES);
2267
                    if (api_get_setting('show_email_addresses') == 'true') {
2268
                        $tutor_info .= Display::tag(
2269
                            'span',
2270
                            Display::encrypted_mailto_link($tutor['mail'], api_get_person_name($tutor['firstName'], $tutor['lastName'])),
2271
                            array('title'=>$username)
2272
                        ).', ';
2273
                    } else {
2274
                        if (api_is_allowed_to_edit()) {
2275
                            $tutor_info .= Display::tag('span', Display::encrypted_mailto_link($tutor['mail'], api_get_person_name($tutor['firstName'], $tutor['lastName'])), array('title'=>$username)).', ';
2276
                        } else {
2277
                            $tutor_info .= Display::tag('span', api_get_person_name($tutor['firstName'], $tutor['lastName']), array('title'=>$username)).', ';
2278
                        }
2279
                    }
2280
                }
2281
            }
2282
2283
            $tutor_info = api_substr($tutor_info, 0, api_strlen($tutor_info) - 2);
2284
            $row[] = $tutor_info;
2285
2286
            // Max number of members in group
2287
            $max_members = ($this_group['maximum_number_of_members'] == self::MEMBER_PER_GROUP_NO_LIMIT ? ' ' : ' / '.$this_group['maximum_number_of_members']);
2288
2289
            // Number of members in group
2290
            $row[] = $this_group['number_of_members'].$max_members;
2291
2292
            // Self-registration / unregistration
2293
            if (!api_is_allowed_to_edit(false, true)) {
2294
                if (self :: is_self_registration_allowed($user_id, $this_group['id'])) {
2295
                    $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>';
2296
                } elseif (self :: is_self_unregistration_allowed($user_id, $this_group['id'])) {
2297
                    $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>';
2298
                } else {
2299
                    $row[] = '-';
2300
                }
2301
            }
2302
2303
            $url = api_get_path(WEB_CODE_PATH).'group/';
2304
            // Edit-links
2305
            if (api_is_allowed_to_edit(false, true) &&
2306
                !(api_is_course_coach() && intval($this_group['session_id']) != $session_id)
2307
            ) {
2308
                $edit_actions = '<a href="'.$url.'settings.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'"  title="'.get_lang('Edit').'">'.
2309
                    Display::return_icon('edit.png', get_lang('EditGroup'),'',ICON_SIZE_SMALL).'</a>&nbsp;';
2310
2311
                if ($this_group['status'] == 1) {
2312
                    $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') . '">' .
2313
                        Display::return_icon('visible.png', get_lang('Hide'), '', ICON_SIZE_SMALL) . '</a>&nbsp;';
2314 View Code Duplication
                } else {
2315
                    $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') . '">' .
2316
                        Display::return_icon('invisible.png', get_lang('Show'), '', ICON_SIZE_SMALL) . '</a>&nbsp;';
2317
                }
2318
2319
                $edit_actions .= '<a href="'.$url.'member_settings.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'"  title="'.get_lang('GroupMembers').'">'.
2320
                    Display::return_icon('user.png', get_lang('GroupMembers'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2321
2322
                $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').'">'.
2323
                    Display::return_icon('export_excel.png', get_lang('Export'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
2324
2325
                /*$edit_actions .= '<a href="'.api_get_self().'?'.api_get_cidreq(true, false).'&category='.$category_id.'&action=empty_one&id='.$this_group['id'].'" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;" title="'.get_lang('EmptyGroup').'">'.
2326
                    Display::return_icon('clean.png',get_lang('EmptyGroup'),'',ICON_SIZE_SMALL).'</a>&nbsp;';*/
2327
2328
                $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').'">'.
2329
                    Display::return_icon('fill.png',get_lang('FillGroup'),'',ICON_SIZE_SMALL).'</a>&nbsp;';
2330
2331
                $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').'">'.
2332
                    Display::return_icon('delete.png', get_lang('Delete'),'',ICON_SIZE_SMALL).'</a>&nbsp;';
2333
2334
                $row[] = $edit_actions;
2335
            }
2336
            if (!empty($this_group['nbMember'])) {
2337
                $totalRegistered = $totalRegistered + $this_group['nbMember'];
2338
            }
2339
            $group_data[] = $row;
2340
        } // end loop
2341
2342
        // If no groups then don't show the table (only for students)
2343
        if (!api_is_allowed_to_edit(true, false)) {
2344
            if (empty($group_data)) {
2345
                return '';
2346
            }
2347
        }
2348
2349
        $table = new SortableTableFromArrayConfig(
2350
            $group_data,
2351
            1,
2352
            20,
2353
            'group_category_'.$category_id
2354
        );
2355
        $table->set_additional_parameters(array('category' => $category_id));
2356
        $column = 0;
2357
        if (api_is_allowed_to_edit(false, true) and count($group_list) > 1) {
2358
            $table->set_header($column++, '', false);
2359
        }
2360
        $table->set_header($column++, get_lang('Groups'));
2361
        $table->set_header($column++, get_lang('GroupTutor'));
2362
        $table->set_header($column++, get_lang('Registered'), false);
2363
2364
        if (!api_is_allowed_to_edit(false, true)) {
2365
            // If self-registration allowed
2366
            $table->set_header($column++, get_lang('GroupSelfRegistration'), false);
2367
        }
2368
2369
        if (api_is_allowed_to_edit(false, true)) {
2370
            // Only for course administrator
2371
            $table->set_header($column++, get_lang('Modify'), false);
2372
            $form_actions = array();
2373
            $form_actions['fill_selected'] = get_lang('FillGroup');
2374
            $form_actions['empty_selected'] = get_lang('EmptyGroup');
2375
            $form_actions['delete_selected'] = get_lang('Delete');
2376
            if (count($group_list) > 1) {
2377
                $table->set_form_actions($form_actions, 'group');
2378
            }
2379
        }
2380
2381
        return $table->return_table();
2382
    }
2383
2384
    /**
2385
     * @param array $groupData
2386
     * @param bool $deleteNotInArray
2387
     * @return array
2388
     */
2389
    public static function importCategoriesAndGroupsFromArray($groupData, $deleteNotInArray = false)
2390
    {
2391
        $result = array();
2392
        $elementsFound = array(
2393
            'categories' => array(),
2394
            'groups' => array()
2395
        );
2396
2397
        $groupCategories = GroupManager::get_categories();
2398
2399
        if (empty($groupCategories)) {
2400
            $result['error'][] = get_lang('CreateACategory');
2401
            return $result;
2402
        }
2403
2404
        foreach ($groupData as $data) {
2405
            $isCategory = empty($data['group']) ? true : false;
2406
            if ($isCategory) {
2407
                $categoryInfo = self::getCategoryByTitle($data['category']);
2408
                $categoryId = $categoryInfo['id'];
2409
2410
                if (!empty($categoryInfo)) {
2411
                    // Update
2412
                    self::update_category(
2413
                        $categoryId,
2414
                        $data['category'],
2415
                        $data['description'],
2416
                        $data['doc_state'],
2417
                        $data['work_state'],
2418
                        $data['calendar_state'],
2419
                        $data['announcements_state'],
2420
                        $data['forum_state'],
2421
                        $data['wiki_state'],
2422
                        $data['chat_state'],
2423
                        $data['self_reg_allowed'],
2424
                        $data['self_unreg_allowed'],
2425
                        $data['max_student'],
2426
                        $data['groups_per_user']
2427
                    );
2428
                    $data['category_id'] = $categoryId;
2429
                    $result['updated']['category'][] = $data;
2430 View Code Duplication
                } else {
2431
2432
                    // Add
2433
                    $categoryId = self::create_category(
2434
                        $data['category'],
2435
                        $data['description'],
2436
                        $data['doc_state'],
2437
                        $data['work_state'],
2438
                        $data['calendar_state'],
2439
                        $data['announcements_state'],
2440
                        $data['forum_state'],
2441
                        $data['wiki_state'],
2442
                        $data['chat_state'],
2443
                        $data['self_reg_allowed'],
2444
                        $data['self_unreg_allowed'],
2445
                        $data['max_student'],
2446
                        $data['groups_per_user']
2447
                    );
2448
2449
                    if ($categoryId) {
2450
                        $data['category_id'] = $categoryId;
2451
                        $result['added']['category'][] = $data;
2452
                    }
2453
                }
2454
                $elementsFound['categories'][] = $categoryId;
2455
            } else {
2456
                $groupInfo = self::getGroupByName($data['group']);
2457
                $categoryInfo = self::getCategoryByTitle($data['category']);
2458
                $categoryId = null;
2459
                if (!empty($categoryInfo)) {
2460
                    $categoryId = $categoryInfo['id'];
2461
                } else {
2462
                    if (!empty($groupCategories) && isset($groupCategories[0])) {
2463
                        $defaultGroupCategory = $groupCategories[0];
2464
                        $categoryId = $defaultGroupCategory['id'];
2465
                    }
2466
                }
2467
2468
                if (empty($groupInfo)) {
2469
2470
                    // Add
2471
                    $groupId = self::create_group(
2472
                        $data['group'],
2473
                        $categoryId,
2474
                        null,
2475
                        $data['max_students']
2476
                    );
2477
2478 View Code Duplication
                    if ($groupId) {
2479
                        self::set_group_properties(
2480
                            $groupId,
2481
                            $data['group'],
2482
                            $data['description'],
2483
                            $data['max_students'],
2484
                            $data['doc_state'],
2485
                            $data['work_state'],
2486
                            $data['calendar_state'],
2487
                            $data['announcements_state'],
2488
                            $data['forum_state'],
2489
                            $data['wiki_state'],
2490
                            $data['chat_state'],
2491
                            $data['self_reg_allowed'],
2492
                            $data['self_unreg_allowed'],
2493
                            $categoryId
2494
                        );
2495
                        $data['group_id'] = $groupId;
2496
                        $result['added']['group'][] = $data;
2497
                    }
2498 View Code Duplication
                } else {
2499
                    // Update
2500
                    $groupId = $groupInfo['id'];
2501
                    self::set_group_properties(
2502
                        $groupId,
2503
                        $data['group'],
2504
                        $data['description'],
2505
                        $data['max_students'],
2506
                        $data['doc_state'],
2507
                        $data['work_state'],
2508
                        $data['calendar_state'],
2509
                        $data['announcements_state'],
2510
                        $data['forum_state'],
2511
                        $data['wiki_state'],
2512
                        $data['chat_state'],
2513
                        $data['self_reg_allowed'],
2514
                        $data['self_unreg_allowed'],
2515
                        $categoryId
2516
                    );
2517
2518
                    $data['group_id'] = $groupId;
2519
                    $result['updated']['group'][] = $data;
2520
                }
2521
2522
                $students = isset($data['students']) ? explode(',', $data['students']) : null;
2523
                if (!empty($students)) {
2524
                    $studentUserIdList = array();
2525
                    foreach ($students as $student) {
2526
                        $userInfo = api_get_user_info_from_username($student);
2527
                        $studentUserIdList[] = $userInfo['user_id'];
2528
                    }
2529
                    self::subscribe_users($studentUserIdList, $groupId);
2530
                }
2531
2532
                $tutors = isset($data['tutors']) ? explode(',', $data['tutors']) : null;
2533
                if (!empty($tutors)) {
2534
                    $tutorIdList = array();
2535
                    foreach ($tutors as $tutor) {
2536
                        $userInfo = api_get_user_info_from_username($tutor);
2537
                        $tutorIdList[] = $userInfo['user_id'];
2538
                    }
2539
                    self::subscribe_tutors($tutorIdList, $groupId);
2540
                }
2541
2542
                $elementsFound['groups'][] = $groupId;
2543
            }
2544
        }
2545
2546
        if ($deleteNotInArray) {
2547
            // Check categories
2548
            $categories = GroupManager::get_categories();
2549 View Code Duplication
            foreach ($categories as $category) {
2550
                if (!in_array($category['id'], $elementsFound['categories'])) {
2551
                    GroupManager::delete_category($category['id']);
2552
                    $category['category'] = $category['title'];
2553
                    $result['deleted']['category'][] = $category;
2554
                }
2555
            }
2556
2557
            $groups = GroupManager::get_groups();
2558 View Code Duplication
            foreach ($groups as $group) {
2559
                if (!in_array($group['id'], $elementsFound['groups'])) {
2560
                    GroupManager::delete_groups(array($group['id']));
2561
                    $group['group'] = $group['name'];
2562
                    $result['deleted']['group'][] = $group;
2563
                }
2564
            }
2565
        }
2566
2567
        return $result;
2568
    }
2569
2570
    /**
2571
     * Export all categories/group from a course to an array.
2572
     * This function works only in a context of a course.
2573
     * @param int $groupId
2574
     * @param bool $loadUsers
2575
     * @return array
2576
     */
2577
    public static function exportCategoriesAndGroupsToArray($groupId = null, $loadUsers = false)
2578
    {
2579
        $data = array();
2580
        $data[] = array(
2581
            'category',
2582
            'group',
2583
            'description',
2584
            'announcements_state',
2585
            'calendar_state',
2586
            'chat_state',
2587
            'doc_state',
2588
            'forum_state',
2589
            'work_state',
2590
            'wiki_state',
2591
            'max_student',
2592
            'self_reg_allowed',
2593
            'self_unreg_allowed',
2594
            'groups_per_user'
2595
        );
2596
2597
        $count = 1;
2598
2599
        if ($loadUsers) {
2600
            $data[0][] = 'students';
2601
            $data[0][] = 'tutors';
2602
        }
2603
2604
        if ($loadUsers == false) {
2605
            $categories = GroupManager::get_categories();
2606
2607
            foreach ($categories as $categoryInfo) {
2608
                $data[$count] = array(
2609
                    $categoryInfo['title'],
2610
                    null,
2611
                    $categoryInfo['description'],
2612
                    $categoryInfo['announcements_state'],
2613
                    $categoryInfo['calendar_state'],
2614
                    $categoryInfo['chat_state'],
2615
                    $categoryInfo['doc_state'],
2616
                    $categoryInfo['forum_state'],
2617
                    $categoryInfo['work_state'],
2618
                    $categoryInfo['wiki_state'],
2619
                    $categoryInfo['max_student'],
2620
                    $categoryInfo['self_reg_allowed'],
2621
                    $categoryInfo['self_unreg_allowed'],
2622
                    $categoryInfo['groups_per_user']
2623
                );
2624
                $count++;
2625
            }
2626
        }
2627
2628
        $groups = GroupManager::get_group_list();
2629
2630
        foreach ($groups as $groupInfo) {
2631
            $categoryTitle = null;
2632
            $categoryInfo = GroupManager::get_category($groupInfo['category_id']);
2633
            $groupSettings = GroupManager::get_group_properties($groupInfo['id']);
2634
            if (!empty($categoryInfo)) {
2635
                $categoryTitle = $categoryInfo['title'];
2636
            }
2637
2638
            $users = GroupManager::getStudents($groupInfo['id']);
2639
            $userList = array();
2640
            foreach ($users as $user) {
2641
                $user = api_get_user_info($user['user_id']);
2642
                $userList[] = $user['username'];
2643
            }
2644
2645
            $tutors = GroupManager::getTutors($groupInfo['id']);
2646
            $tutorList = array();
2647
            foreach ($tutors as $user) {
2648
                $user = api_get_user_info($user['user_id']);
2649
                $tutorList[] = $user['username'];
2650
            }
2651
2652
            $userListToString = null;
2653
            if (!empty($userList)) {
2654
                $userListToString = implode(',', $userList);
2655
            }
2656
2657
            $tutorListToString = null;
2658
            if (!empty($tutorList)) {
2659
                $tutorListToString = implode(',', $tutorList);
2660
            }
2661
2662
            $data[$count] = array(
2663
                $categoryTitle,
2664
                $groupSettings['name'],
2665
                $groupSettings['description'],
2666
                $groupSettings['announcements_state'],
2667
                $groupSettings['calendar_state'],
2668
                $groupSettings['chat_state'],
2669
                $groupSettings['doc_state'],
2670
                $groupSettings['forum_state'],
2671
                $groupSettings['work_state'],
2672
                $groupSettings['wiki_state'],
2673
                $groupSettings['maximum_number_of_students'],
2674
                $groupSettings['self_registration_allowed'],
2675
                $groupSettings['self_unregistration_allowed'],
2676
                null
2677
            );
2678
2679
            if ($loadUsers) {
2680
                $data[$count][] = $userListToString;
2681
                $data[$count][] = $tutorListToString;
2682
            }
2683
2684
            if (!empty($groupId)) {
2685
                if ($groupId == $groupInfo['id']) {
2686
                    break;
2687
                }
2688
            }
2689
            $count++;
2690
        }
2691
2692
        return $data;
2693
    }
2694
2695
    /**
2696
     * @param string $default
2697
     */
2698
    static function getSettingBar($default)
2699
    {
2700
        $activeSettings = null;
2701
        $activeTutor = null;
2702
        $activeMember = null;
2703
2704
        switch($default) {
2705
            case 'settings':
2706
                $activeSettings = 'active';
2707
                break;
2708
            case'tutor':
2709
                $activeTutor = 'active';
2710
                break;
2711
            case 'member':
2712
                $activeMember = 'active';
2713
                break;
2714
        }
2715
2716
        $url = api_get_path(WEB_CODE_PATH).'group/%s?'.api_get_cidreq();
2717
2718
        echo '
2719
            <ul class="toolbar-groups nav nav-tabs">
2720
                <li class="'.$activeSettings.'">
2721
                    <a href="'.sprintf($url, 'settings.php').'">
2722
                    '.Display::return_icon('settings.png').' '.get_lang('Settings').'
2723
                    </a>
2724
                </li>
2725
                <li class="'.$activeMember.'">
2726
                    <a href="'.sprintf($url, 'member_settings.php').'">
2727
                    '.Display::return_icon('user.png').' '.get_lang('GroupMembers').'
2728
                    </a>
2729
                </li>
2730
                <li class="'.$activeTutor.'">
2731
                    <a href="'.sprintf($url, 'tutor_settings.php').'">
2732
                    '.Display::return_icon('teacher.png').' '.get_lang('GroupTutors').'
2733
                    </a>
2734
                </li>
2735
            </ul>';
2736
    }
2737
2738
    /**
2739
     * @param int $courseId
2740
     * @param string $keyword
2741
     * @return string
2742
     */
2743
    public static function getOverview($courseId, $keyword = null)
2744
    {
2745
        $content = null;
2746
        $categories = GroupManager::get_categories();
2747
        if (!empty($categories)) {
2748
2749
            foreach ($categories as $category) {
2750
                if (api_get_setting('allow_group_categories') == 'true') {
2751
                    $content .= '<h2>'.$category['title'].'</h2>';
2752
                }
2753
                if (!empty($keyword)) {
2754
                    $groups = GroupManager::getGroupListFilterByName($keyword, $category['id'], $courseId);
2755
                } else {
2756
                    $groups = GroupManager::get_group_list($category['id']);
2757
                }
2758
2759
                if (empty($groups)) {
2760
                    $groups = GroupManager::get_group_list();
2761
                }
2762
2763
                $content .= '<ul>';
2764
                if (!empty($groups)) {
2765
                    foreach ($groups as $group) {
2766
                        $content .= '<li>';
2767
                        $content .= Display::tag('h3', Security::remove_XSS($group['name']));
2768
2769
                        $users = GroupManager::getTutors($group['id']);
2770 View Code Duplication
                        if (!empty($users)) {
2771
                            $content .= '<ul>';
2772
                            $content .= "<li>".Display::tag('h4', get_lang('Tutors'))."</li><ul>";
2773
                            foreach ($users as $user) {
2774
                                $user_info = api_get_user_info($user['user_id']);
2775
                                $content .= '<li title="'.$user_info['username'].'">'.
2776
                                    $user_info['complete_name_with_username'].
2777
                                '</li>';
2778
                            }
2779
                            $content .= '</ul>';
2780
                            $content .= '</ul>';
2781
                        }
2782
2783
                        $users = GroupManager::getStudents($group['id']);
2784 View Code Duplication
                        if (!empty($users)) {
2785
                            $content .= '<ul>';
2786
                            $content .= "<li>".Display::tag('h4', get_lang('Students'))."</li><ul>";
2787
                            foreach ($users as $user) {
2788
                                $user_info = api_get_user_info($user['user_id']);
2789
                                $content .= '<li title="'.$user_info['username'].'">'.
2790
                                    $user_info['complete_name_with_username'].
2791
                                    '</li>';
2792
                            }
2793
                            $content .= '</ul>';
2794
                            $content .= '</ul>';
2795
                        }
2796
                        $content .= '</li>';
2797
                    }
2798
                }
2799
                $content .= '</ul>';
2800
            }
2801
        }
2802
2803
        return $content;
2804
    }
2805
2806
    /**
2807
     * Returns the search form
2808
     * @return string
2809
     */
2810
    public static function getSearchForm()
2811
    {
2812
        $url = api_get_path(WEB_CODE_PATH).'group/group_overview.php?'.api_get_cidreq();
2813
        $form = new FormValidator(
2814
            'search_groups',
2815
            'get',
2816
            $url,
2817
            null,
2818
            array('class' => 'form-search'),
2819
            FormValidator::LAYOUT_INLINE
2820
        );
2821
        $form->addElement('text', 'keyword');
2822
        $form->addButtonSearch();
2823
        return $form->toHtml();
2824
    }
2825
2826
    /**
2827
     * @param int $groupId
2828
     * @param int $status
2829
     */
2830
    public static function setStatus($groupId, $status)
2831
    {
2832
        $groupInfo = self::get_group_properties($groupId);
2833
2834
        $courseId = api_get_course_int_id();
2835
        if (!empty($groupInfo)) {
2836
            $table = Database::get_course_table(TABLE_GROUP);
2837
            $params = array(
2838
                'status' => intval($status)
2839
            );
2840
            Database::update(
2841
                $table,
2842
                $params,
2843
                array('c_id = ? AND id = ?' => array($courseId, $groupId))
2844
            );
2845
        }
2846
    }
2847
2848
    /**
2849
     * @param int $groupId
2850
     */
2851
    public static function setVisible($groupId)
2852
    {
2853
        self::setStatus($groupId, 1);
2854
    }
2855
2856
    /**
2857
     * @param int $groupId
2858
     */
2859
    public static function setInvisible($groupId)
2860
    {
2861
        self::setStatus($groupId, 0);
2862
    }
2863
}
2864