UserGroup   F
last analyzed

Complexity

Total Complexity 435

Size/Duplication

Total Lines 3437
Duplicated Lines 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
wmc 435
eloc 1730
c 3
b 1
f 0
dl 0
loc 3437
rs 0.8

78 Methods

Rating   Name   Duplication   Size   Complexity  
A getUserGroupByCourseWithDataCount() 0 41 5
A displayToolBarUserGroupUsers() 0 18 2
A returnGrid() 0 30 2
A getUseMultipleUrl() 0 3 1
C getUserGroupUsers() 0 96 14
A display_teacher_view() 0 3 1
A getTotalCount() 0 21 2
B get_count() 0 43 6
B get_courses_by_usergroup() 0 44 7
A getIdByName() 0 14 2
A __construct() 0 17 2
A usergroup_was_added_in_course() 0 27 5
F getUserGroupNotInCourse() 0 97 15
A get_usergroup_by_course() 0 29 4
C getUserGroupInCourse() 0 85 13
B get_users_by_usergroup() 0 38 7
A get_sessions_by_usergroup() 0 28 5
A is_group_member() 0 19 4
A getGroupType() 0 3 1
A getNameListByUser() 0 5 1
A canLeave() 0 3 2
A setGroupType() 0 3 1
B get_groups_by_popularity() 0 54 6
B getGroupsByDepthLevel() 0 39 7
A update_user_role() 0 11 1
C subscribe_courses_to_usergroup() 0 103 16
A get_usergroup_by_user() 0 28 4
A getGroupsByLp() 0 16 1
A userExists() 0 9 2
B get_picture_group() 0 51 10
A get_groups_by_user_count() 0 30 3
A getUserListByUserGroup() 0 16 2
A groupExists() 0 9 2
A getGroupStatusList() 0 8 1
B get_groups_by_user() 0 61 7
B update() 0 35 9
A delete() 0 32 3
B getGroupUsersByUser() 0 42 8
C show_group_column_information() 0 88 16
A delete_user_rel_group() 0 25 3
A delete_topic() 0 13 1
A subscribeToUrl() 0 7 1
B add_users_to_groups() 0 42 7
A allowTeachers() 0 3 1
A delete_group_picture() 0 3 1
B add_user_to_group() 0 35 6
A manageFileUpload() 0 11 2
B get_groups_by_age() 0 62 6
A getUsersByUsergroupAndRelation() 0 34 5
A getGroupsByLpCategory() 0 17 1
A is_group_admin() 0 10 3
A searchUserGroupAjax() 0 32 4
A get_user_group_role() 0 21 4
A getAllowedPictureExtensions() 0 3 1
B get_parent_groups() 0 37 7
C get_group_picture_path_by_id() 0 45 13
A getUserRoleToString() 0 24 6
A getLabelsFromNameList() 0 16 3
A getUserGroupListByUser() 0 37 5
A unsubscribeToUrl() 0 6 1
C subscribe_sessions_to_usergroup() 0 81 17
A usergroup_exists() 0 16 2
B getUsergroupsPagination() 0 70 11
B get_users_by_group() 0 65 9
B unsubscribeSessionsFromUserGroup() 0 41 7
C getDataToExport() 0 60 13
B unsubscribe_courses_from_usergroup() 0 42 7
B setForm() 0 61 7
A isGroupModerator() 0 10 3
C update_group_picture() 0 113 15
B protectScript() 0 25 10
D subscribe_users_to_usergroup() 0 156 25
A get_all_users_by_group() 0 24 3
A setParentGroup() 0 25 3
B get_all_group_tags() 0 50 7
A filterByFirstLetter() 0 31 3
A getUserGroupNotInList() 0 12 2
B save() 0 48 10

How to fix   Complexity   

Complex Class

Complex classes like UserGroup often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use UserGroup, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
/**
6
 * Class UserGroup.
7
 *
8
 * This class provides methods for the UserGroup management.
9
 * Include/require it in your code to use its features.
10
 */
11
class UserGroup extends Model
12
{
13
    public const SOCIAL_CLASS = 1;
14
    public const NORMAL_CLASS = 0;
15
    public $columns = [
16
        'id',
17
        'name',
18
        'description',
19
        'group_type',
20
        'picture',
21
        'url',
22
        'allow_members_leave_group',
23
        'visibility',
24
        'updated_at',
25
        'created_at',
26
    ];
27
28
    public $useMultipleUrl = false;
29
    public $groupType = 0;
30
    public $showGroupTypeSetting = false;
31
    public $usergroup_rel_user_table;
32
    public $usergroup_rel_course_table;
33
    public $usergroup;
34
    public $usergroup_rel_session_table;
35
    public $session_table;
36
    public $access_url_rel_usergroup;
37
    public $session_rel_course_table;
38
    public $access_url_rel_user;
39
    public $table_course;
40
    public $table_user;
41
42
    /**
43
     * Set ups DB tables.
44
     */
45
    public function __construct()
46
    {
47
        parent::__construct();
48
        $this->table = Database::get_main_table(TABLE_USERGROUP);
49
        $this->usergroup_rel_user_table = Database::get_main_table(TABLE_USERGROUP_REL_USER);
50
        $this->usergroup_rel_course_table = Database::get_main_table(TABLE_USERGROUP_REL_COURSE);
51
        $this->usergroup_rel_session_table = Database::get_main_table(TABLE_USERGROUP_REL_SESSION);
52
        $this->session_table = Database::get_main_table(TABLE_MAIN_SESSION);
53
        $this->usergroup_table = Database::get_main_table(TABLE_USERGROUP);
54
        $this->access_url_rel_usergroup = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USERGROUP);
55
        $this->session_rel_course_table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
56
        $this->access_url_rel_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
57
        $this->table_course = Database::get_main_table(TABLE_MAIN_COURSE);
58
        $this->table_user = Database::get_main_table(TABLE_MAIN_USER);
59
        $this->useMultipleUrl = api_get_configuration_value('multiple_access_urls');
60
        if ($this->allowTeachers()) {
61
            $this->columns[] = 'author_id';
62
        }
63
    }
64
65
    /**
66
     * @return bool
67
     */
68
    public function getUseMultipleUrl()
69
    {
70
        return $this->useMultipleUrl;
71
    }
72
73
    /**
74
     * @return int
75
     */
76
    public function getTotalCount()
77
    {
78
        $options = [];
79
        $from = $this->table;
80
81
        if ($this->getUseMultipleUrl()) {
82
            $urlId = api_get_current_access_url_id();
83
            $options = [
84
                'where' => [
85
                    'access_url_id = ?' => [
86
                        $urlId,
87
                    ],
88
                ],
89
            ];
90
            $from = " $this->table u
91
                      INNER JOIN $this->access_url_rel_usergroup a
92
                      ON (u.id = a.usergroup_id) ";
93
        }
94
        $row = Database::select('count(*) as count', $from, $options, 'first');
95
96
        return $row['count'];
97
    }
98
99
    /**
100
     * @param int  $id       user group id
101
     * @param bool $getCount
102
     *
103
     * @return array|int
104
     */
105
    public function getUserGroupUsers($id, $getCount = false, $start = 0, $limit = 0)
106
    {
107
        $id = (int) $id;
108
        $start = (int) $start;
109
        $limit = (int) $limit;
110
111
        $select = ' u.* ';
112
        if ($getCount) {
113
            $select = 'COUNT(u.id) count ';
114
        }
115
116
        if ($this->getUseMultipleUrl()) {
117
            $urlId = api_get_current_access_url_id();
118
            $sql = "SELECT $select
119
                    FROM $this->usergroup_rel_user_table u
120
                    INNER JOIN $this->access_url_rel_user a
121
                    ON (u.user_id = a.user_id)
122
                    WHERE u.usergroup_id = $id AND access_url_id = $urlId ";
123
        } else {
124
            $sql = "SELECT $select
125
                    FROM $this->usergroup_rel_user_table u
126
                    WHERE u.usergroup_id = $id";
127
        }
128
        $limitCondition = '';
129
        if (!empty($start) && !empty($limit)) {
130
            $limitCondition = " LIMIT $start, $limit";
131
        }
132
133
        $sql .= $limitCondition;
134
135
        $result = Database::query($sql);
136
137
        if ($getCount) {
138
            if (Database::num_rows($result)) {
139
                $row = Database::fetch_array($result);
140
141
                return $row['count'];
142
            }
143
144
            return 0;
145
        } else {
146
            $list = [];
147
            $showCalendar = 'true' === api_get_plugin_setting('learning_calendar', 'enabled');
148
            $calendarPlugin = null;
149
            if ($showCalendar) {
150
                $calendarPlugin = LearningCalendarPlugin::create();
151
            }
152
            $url = api_get_path(WEB_PLUGIN_PATH).'learning_calendar/calendar.php?';
153
            while ($data = Database::fetch_array($result)) {
154
                $userId = $data['user_id'];
155
                $userInfo = api_get_user_info($userId);
156
                $data['name'] = $userInfo['complete_name_with_username'];
157
158
                if ($showCalendar) {
159
                    $calendar = $calendarPlugin->getUserCalendar($userId);
160
                    $data['calendar_id'] = 0;
161
                    $data['calendar'] = '';
162
                    if (!empty($calendar)) {
163
                        $calendarInfo = $calendarPlugin->getCalendar($calendar['calendar_id']);
164
                        if ($calendarInfo) {
165
                            $data['calendar_id'] = $calendar['calendar_id'];
166
                            $data['calendar'] = Display::url(
167
                                $calendarInfo['title'],
168
                                $url.'&id='.$calendar['calendar_id']
169
                            );
170
                        }
171
                    }
172
173
                    $courseAndSessionList = Tracking::showUserProgress(
174
                        $userId,
175
                        0,
176
                        '',
177
                        true,
178
                        true,
179
                        true
180
                    );
181
182
                    $stats = $calendarPlugin->getUserStats($userId, $courseAndSessionList);
183
                    $evaluations = $calendarPlugin->getGradebookEvaluationListToString($userId, $courseAndSessionList);
184
                    $data['gradebook_items'] = $evaluations;
185
                    $totalTime = 0;
186
                    foreach ($courseAndSessionList as $sessionId => $course) {
187
                        foreach ($course as $courseId) {
188
                            $totalTime += Tracking::get_time_spent_on_the_course($userId, $courseId, $sessionId);
189
                        }
190
                    }
191
192
                    $data['time_spent'] = api_time_to_hms($totalTime);
193
                    $data['lp_day_completed'] = $stats['completed'];
194
                    $data['days_diff'] = $stats['completed'] - $stats['user_event_count'];
195
                }
196
                $data['id'] = $data['user_id'];
197
                $list[] = $data;
198
            }
199
200
            return $list;
201
        }
202
    }
203
204
    /**
205
     * @param string $extraWhereCondition
206
     *
207
     * @return int
208
     */
209
    public function get_count($extraWhereCondition = '')
210
    {
211
        $authorCondition = '';
212
213
        if ($this->allowTeachers()) {
214
            if (!api_is_platform_admin()) {
215
                $userId = api_get_user_id();
216
                $authorCondition = " AND author_id = $userId";
217
            }
218
        }
219
220
        if ($this->getUseMultipleUrl()) {
221
            $urlId = api_get_current_access_url_id();
222
            $sql = "SELECT count(u.id) as count
223
                    FROM $this->table u
224
                    INNER JOIN $this->access_url_rel_usergroup a
225
                    ON (u.id = a.usergroup_id)
226
                    WHERE access_url_id = $urlId $authorCondition
227
                    AND $extraWhereCondition
228
            ";
229
230
            $result = Database::query($sql);
231
            if (Database::num_rows($result)) {
232
                $row = Database::fetch_array($result);
233
234
                return $row['count'];
235
            }
236
        } else {
237
            $sql = "SELECT count(a.id) as count
238
                    FROM {$this->table} a
239
                    WHERE 1 = 1
240
                    $authorCondition
241
                    AND $extraWhereCondition
242
            ";
243
            $result = Database::query($sql);
244
            if (Database::num_rows($result)) {
245
                $row = Database::fetch_array($result);
246
247
                return $row['count'];
248
            }
249
        }
250
251
        return 0;
252
    }
253
254
    /**
255
     * @param int $course_id
256
     * @param int $type
257
     *
258
     * @return mixed
259
     */
260
    public function getUserGroupByCourseWithDataCount($course_id, $type = -1)
261
    {
262
        if ($this->getUseMultipleUrl()) {
263
            $course_id = (int) $course_id;
264
            $urlId = api_get_current_access_url_id();
265
            $sql = "SELECT count(c.usergroup_id) as count
266
                    FROM {$this->usergroup_rel_course_table} c
267
                    INNER JOIN {$this->access_url_rel_usergroup} a
268
                    ON (c.usergroup_id = a.usergroup_id)
269
                    WHERE access_url_id = $urlId AND course_id = $course_id
270
            ";
271
            $result = Database::query($sql);
272
            if (Database::num_rows($result)) {
273
                $row = Database::fetch_array($result);
274
275
                return $row['count'];
276
            }
277
278
            return 0;
279
        } else {
280
            $typeCondition = '';
281
            if ($type != -1) {
282
                $type = (int) $type;
283
                $typeCondition = " AND group_type = $type ";
284
            }
285
            $sql = "SELECT count(c.usergroup_id) as count
286
                    FROM {$this->usergroup_rel_course_table} c
287
                    INNER JOIN {$this->table} a
288
                    ON (c.usergroup_id = a.id)
289
                    WHERE
290
                        course_id = $course_id
291
                        $typeCondition
292
            ";
293
            $result = Database::query($sql);
294
            if (Database::num_rows($result)) {
295
                $row = Database::fetch_array($result);
296
297
                return $row['count'];
298
            }
299
300
            return 0;
301
        }
302
    }
303
304
    /**
305
     * @param string $name
306
     *
307
     * @return int
308
     */
309
    public function getIdByName($name)
310
    {
311
        $row = Database::select(
312
            'id',
313
            $this->table,
314
            ['where' => ['name = ?' => $name]],
315
            'first'
316
        );
317
318
        if ($row) {
319
            return (int) $row['id'];
320
        }
321
322
        return 0;
323
    }
324
325
    /**
326
     * Displays the title + grid.
327
     */
328
    public function returnGrid()
329
    {
330
        // action links
331
        $html = '<div class="actions">';
332
        if (api_is_platform_admin()) {
333
            $html .= '<a href="../admin/index.php">'.
334
                Display::return_icon(
335
                    'back.png',
336
                    get_lang('BackTo').' '.get_lang('PlatformAdmin'),
337
                    '',
338
                    ICON_SIZE_MEDIUM
339
                ).
340
                '</a>';
341
        }
342
343
        $html .= '<a href="'.api_get_self().'?action=add">'.
344
            Display::return_icon('new_class.png', get_lang('AddClasses'), '', ICON_SIZE_MEDIUM).
345
            '</a>';
346
        $html .= Display::url(
347
            Display::return_icon('import_csv.png', get_lang('Import'), [], ICON_SIZE_MEDIUM),
348
            'usergroup_import.php'
349
        );
350
        $html .= Display::url(
351
            Display::return_icon('export_csv.png', get_lang('Export'), [], ICON_SIZE_MEDIUM),
352
            'usergroup_export.php'
353
        );
354
        $html .= '</div>';
355
        $html .= Display::grid_html('usergroups');
356
357
        return $html;
358
    }
359
360
    /**
361
     * Displays the title + grid.
362
     */
363
    public function displayToolBarUserGroupUsers()
364
    {
365
        // action links
366
        echo '<div class="actions">';
367
        $courseInfo = api_get_course_info();
368
        if (empty($courseInfo)) {
369
            echo '<a href="../admin/usergroups.php">'.
370
                Display::return_icon('back.png', get_lang('BackTo').' '.get_lang('PlatformAdmin'), '', '32').
371
                '</a>';
372
        } else {
373
            echo Display::url(
374
                Display::return_icon('back.png', get_lang('BackTo').' '.get_lang('PlatformAdmin'), '', '32'),
375
                api_get_path(WEB_CODE_PATH).'user/class.php?'.api_get_cidreq()
376
            );
377
        }
378
379
        echo '</div>';
380
        echo Display::grid_html('usergroups');
381
    }
382
383
    /**
384
     * Get HTML grid.
385
     */
386
    public function display_teacher_view()
387
    {
388
        echo Display::grid_html('usergroups');
389
    }
390
391
    /**
392
     * Gets a list of course ids by user group.
393
     *
394
     * @param int  $id             user group id
395
     * @param bool $loadCourseData
396
     *
397
     * @return array
398
     */
399
    public function get_courses_by_usergroup($id, $loadCourseData = false)
400
    {
401
        if ($this->getUseMultipleUrl()) {
402
            $urlId = api_get_current_access_url_id();
403
            $from = $this->usergroup_rel_course_table." c
404
                    INNER JOIN {$this->access_url_rel_usergroup} a
405
                    ON (a.usergroup_id = c.usergroup_id) ";
406
            $whereConditionSql = 'a.usergroup_id = ? AND access_url_id = ? ';
407
            $whereConditionValues = [$id, $urlId];
408
        } else {
409
            $whereConditionSql = 'usergroup_id = ?';
410
            $whereConditionValues = [$id];
411
            $from = $this->usergroup_rel_course_table.' c ';
412
        }
413
414
        if ($loadCourseData) {
415
            $from .= " INNER JOIN {$this->table_course} as course ON c.course_id = course.id";
416
        }
417
418
        $where = ['where' => [$whereConditionSql => $whereConditionValues]];
419
420
        $select = 'course_id';
421
        if ($loadCourseData) {
422
            $select = 'course.*';
423
        }
424
425
        $results = Database::select(
426
            $select,
427
            $from,
428
            $where
429
        );
430
431
        $array = [];
432
        if (!empty($results)) {
433
            foreach ($results as $row) {
434
                if ($loadCourseData) {
435
                    $array[$row['id']] = $row;
436
                } else {
437
                    $array[] = $row['course_id'];
438
                }
439
            }
440
        }
441
442
        return $array;
443
    }
444
445
    /**
446
     * Gets all users that are part of a group or class.
447
     *
448
     * @param array $options
449
     * @param int   $type    0 = classes / 1 = social groups
450
     *
451
     * @return array
452
     */
453
    public function getUserGroupInCourse($options = [], $type = -1, $getCount = false)
454
    {
455
        $select = 'DISTINCT u.*';
456
        if ($getCount) {
457
            $select = 'count(u.id) as count';
458
        }
459
460
        $sessionCheck = false;
461
        if (isset($options['session_id']) && !empty($options['session_id'])) {
462
            $sessionCheck = true;
463
        }
464
465
        if ($this->getUseMultipleUrl()) {
466
            if (false === $sessionCheck) {
467
                $sql = "SELECT $select
468
                        FROM {$this->usergroup_rel_course_table} usergroup
469
                        INNER JOIN {$this->table} u
470
                        ON (u.id = usergroup.usergroup_id)
471
                        INNER JOIN {$this->table_course} c
472
                        ON (usergroup.course_id = c.id)
473
                        INNER JOIN {$this->access_url_rel_usergroup} a
474
                        ON (a.usergroup_id = u.id)
475
                   ";
476
            } else {
477
                $sql = "SELECT $select
478
                        FROM {$this->usergroup_rel_session_table} usergroup
479
                        INNER JOIN {$this->table} u
480
                        ON (u.id = usergroup.usergroup_id)
481
                        INNER JOIN {$this->session_table} s
482
                        ON (usergroup.session_id = s.id)
483
                        INNER JOIN {$this->access_url_rel_usergroup} a
484
                        ON (a.usergroup_id = u.id)
485
                   ";
486
            }
487
        } else {
488
            if (false === $sessionCheck) {
489
                $sql = "SELECT $select
490
                        FROM {$this->usergroup_rel_course_table} usergroup
491
                        INNER JOIN {$this->table} u
492
                        ON (u.id = usergroup.usergroup_id)
493
                        INNER JOIN {$this->table_course} c
494
                        ON (usergroup.course_id = c.id)
495
                       ";
496
            } else {
497
                $sql = "SELECT $select
498
                        FROM {$this->usergroup_rel_session_table} usergroup
499
                        INNER JOIN {$this->table} u
500
                        ON (u.id = usergroup.usergroup_id)
501
                        INNER JOIN {$this->session_table} s
502
                        ON (usergroup.session_id = s.id)
503
                       ";
504
            }
505
        }
506
507
        if (-1 != $type) {
508
            $type = (int) $type;
509
            $options['where']['AND group_type = ? '] = $type;
510
        }
511
        if ($this->getUseMultipleUrl()) {
512
            $urlId = api_get_current_access_url_id();
513
            $options['where']['AND access_url_id = ? '] = $urlId;
514
        }
515
516
        $conditions = Database::parse_conditions($options);
517
        $sql .= $conditions;
518
        $result = Database::query($sql);
519
520
        if ($getCount) {
521
            if (Database::num_rows($result)) {
522
                $row = Database::fetch_array($result);
523
524
                return (int) $row['count'];
525
            }
526
527
            return 0;
528
        }
529
530
        $data = [];
531
        if (Database::num_rows($result) > 0) {
532
            while ($row = Database::fetch_array($result, 'ASSOC')) {
533
                $data[] = $row;
534
            }
535
        }
536
537
        return $data;
538
    }
539
540
    /**
541
     * @param array $options
542
     * @param int   $type
543
     * @param bool  $getCount
544
     *
545
     * @return array|bool
546
     */
547
    public function getUserGroupNotInCourse($options = [], $type = -1, $getCount = false)
548
    {
549
        $courseId = 0;
550
        if (isset($options['course_id'])) {
551
            $courseId = (int) $options['course_id'];
552
            unset($options['course_id']);
553
        }
554
555
        if (empty($courseId)) {
556
            return false;
557
        }
558
559
        $select = 'DISTINCT u.*';
560
        if ($getCount) {
561
            $select = 'count(u.id) as count';
562
        }
563
564
        $sessionCheck = false;
565
        $sessionId = 0;
566
        if (isset($options['session_id']) && !empty($options['session_id'])) {
567
            $sessionCheck = true;
568
            $sessionId = (int) $options['session_id'];
569
        }
570
571
        if ($this->getUseMultipleUrl()) {
572
            if (false === $sessionCheck) {
573
                $sql = "SELECT $select
574
                        FROM {$this->table} u
575
                        INNER JOIN {$this->access_url_rel_usergroup} a
576
                        ON (a.usergroup_id = u.id)
577
                        LEFT OUTER JOIN {$this->usergroup_rel_course_table} urc
578
                        ON (u.id = urc.usergroup_id AND course_id = $courseId)
579
                ";
580
            } else {
581
                $sql = "SELECT $select
582
                        FROM {$this->table} u
583
                        INNER JOIN {$this->access_url_rel_usergroup} a
584
                        ON (a.usergroup_id = u.id)
585
                        LEFT OUTER JOIN {$this->usergroup_rel_session_table} urs
586
                        ON (u.id = urs.usergroup_id AND session_id = $sessionId)
587
                ";
588
            }
589
        } else {
590
            if (false === $sessionCheck) {
591
                $sql = "SELECT $select
592
                        FROM {$this->table} u
593
                        LEFT OUTER JOIN {$this->usergroup_rel_course_table} urc
594
                        ON (u.id = urc.usergroup_id AND course_id = $courseId)
595
                ";
596
            } else {
597
                $sql = "SELECT $select
598
                        FROM {$this->table} u
599
                        LEFT OUTER JOIN {$this->usergroup_rel_session_table} urc
600
                        ON (u.id = urc.usergroup_id AND session_id = $sessionId)
601
                ";
602
            }
603
        }
604
605
        if (-1 != $type) {
606
            $type = (int) $type;
607
            $options['where']['AND group_type = ? '] = $type;
608
        }
609
        if ($this->getUseMultipleUrl()) {
610
            $urlId = api_get_current_access_url_id();
611
            $options['where']['AND access_url_id = ? '] = $urlId;
612
        }
613
614
        /*if ($this->allowTeachers()) {
615
            if (!api_is_platform_admin()) {
616
                $userId = api_get_user_id();
617
                $options['where']['AND author_id = ? '] = $userId;
618
            }
619
        }*/
620
621
        $conditions = Database::parse_conditions($options);
622
        $sql .= $conditions;
623
        $result = Database::query($sql);
624
625
        if ($getCount) {
626
            $result = Database::query($sql);
627
            if (Database::num_rows($result)) {
628
                $array = Database::fetch_array($result, 'ASSOC');
629
630
                return $array['count'];
631
            }
632
633
            return 0;
634
        }
635
636
        $data = [];
637
        if (Database::num_rows($result) > 0) {
638
            while ($row = Database::fetch_array($result, 'ASSOC')) {
639
                $data[] = $row;
640
            }
641
        }
642
643
        return $data;
644
    }
645
646
    /**
647
     * @param int $course_id
648
     *
649
     * @deprecated  ?
650
     *
651
     * @return array
652
     */
653
    public function get_usergroup_by_course($course_id)
654
    {
655
        if ($this->getUseMultipleUrl()) {
656
            $urlId = api_get_current_access_url_id();
657
            $options = [
658
                'where' => [
659
                    'c.course_id = ? AND access_url_id = ?' => [
660
                        $course_id,
661
                        $urlId,
662
                    ],
663
                ],
664
            ];
665
            $from = " $this->usergroup_rel_course_table as c
666
                    INNER JOIN $this->access_url_rel_usergroup a
667
                    ON c.usergroup_id = a.usergroup_id ";
668
        } else {
669
            $options = ['where' => ['c.course_id = ?' => $course_id]];
670
            $from = $this->usergroup_rel_course_table." c";
671
        }
672
673
        $results = Database::select('c.usergroup_id', $from, $options);
674
        $array = [];
675
        if (!empty($results)) {
676
            foreach ($results as $row) {
677
                $array[] = $row['usergroup_id'];
678
            }
679
        }
680
681
        return $array;
682
    }
683
684
    /**
685
     * @param int $usergroup_id
686
     * @param int $course_id
687
     *
688
     * @return bool
689
     */
690
    public function usergroup_was_added_in_course(
691
        $usergroup_id,
692
        $course_id,
693
        $Session = 0
694
    ) {
695
        $Session = (int) $Session;
696
697
        $results = Database::select(
698
            'usergroup_id',
699
            $this->usergroup_rel_course_table,
700
            ['where' => ['course_id = ? AND usergroup_id = ?' => [$course_id, $usergroup_id]]]
701
        );
702
703
        $resultSession = Database::select(
704
            'usergroup_id',
705
            $this->usergroup_rel_session_table,
706
            ['where' => ['session_id = ? AND usergroup_id = ?' => [$Session, $usergroup_id]]]
707
        );
708
709
        if (empty($results) && $Session == 0) {
710
            return false;
711
        }
712
        if ((empty($resultSession)) && $Session != 0) {
713
            return false;
714
        }
715
716
        return true;
717
    }
718
719
    /**
720
     * Gets a list of session ids by user group.
721
     *
722
     * @param int  $id                group id
723
     * @param bool $returnSessionData Whether to return an array with info (true) or just the session ID (false)
724
     *
725
     * @return array
726
     */
727
    public function get_sessions_by_usergroup($id, $returnSessionData = false)
728
    {
729
        if ($returnSessionData) {
730
            $results = Database::select(
731
                'g.session_id, s.name, s.description, s.nbr_users, s.nbr_courses',
732
                $this->usergroup_rel_session_table." g, ".$this->session_table." s",
733
                ['where' => ['g.session_id = s.id AND g.usergroup_id = ?' => $id]]
734
            );
735
        } else {
736
            $results = Database::select(
737
                'session_id',
738
                $this->usergroup_rel_session_table,
739
                ['where' => ['usergroup_id = ?' => $id]]
740
            );
741
        }
742
743
        $array = [];
744
        if (!empty($results)) {
745
            foreach ($results as $row) {
746
                if ($returnSessionData) {
747
                    $array[$row['session_id']] = $row;
748
                } else {
749
                    $array[] = $row['session_id'];
750
                }
751
            }
752
        }
753
754
        return $array;
755
    }
756
757
    /**
758
     * Gets a list of user ids by user group.
759
     *
760
     * @param int   $id    user group id
761
     * @param array $roles
762
     *
763
     * @return array with a list of user ids
764
     */
765
    public function get_users_by_usergroup($id = null, $roles = [])
766
    {
767
        $relationCondition = '';
768
        if (!empty($roles)) {
769
            $relationConditionArray = [];
770
            foreach ($roles as $relation) {
771
                $relation = (int) $relation;
772
                if (empty($relation)) {
773
                    $relationConditionArray[] = " (relation_type = 0 OR relation_type IS NULL OR relation_type = '') ";
774
                } else {
775
                    $relationConditionArray[] = " relation_type = $relation ";
776
                }
777
            }
778
            $relationCondition = ' AND ( ';
779
            $relationCondition .= implode('OR', $relationConditionArray);
780
            $relationCondition .= ' ) ';
781
        }
782
783
        if (empty($id)) {
784
            $conditions = [];
785
        } else {
786
            $conditions = ['where' => ["usergroup_id = ? $relationCondition " => $id]];
787
        }
788
789
        $results = Database::select(
790
            'user_id',
791
            $this->usergroup_rel_user_table,
792
            $conditions
793
        );
794
795
        $array = [];
796
        if (!empty($results)) {
797
            foreach ($results as $row) {
798
                $array[] = $row['user_id'];
799
            }
800
        }
801
802
        return $array;
803
    }
804
805
    /**
806
     * Retrieves a list of user IDs belonging to a user group based on a specific type of relation.
807
     *
808
     * @param int   $id       The ID of the user group.
809
     * @param int   $relation The type of relation to consider. Defaults to 0, which implies any type of relation.
810
     * @param array $order    Optional. An array of columns to sort the results by.
811
     *                        Each element of the array should be a column name, and the sorting is ascending by default.
812
     *                        Example: ['firstname', 'lastname'] translates to 'ORDER BY firstname ASC, lastname ASC'.
813
     *
814
     * @return array A list of user IDs that meet the specified criteria.
815
     *               If no users are found, an empty array is returned.
816
     */
817
    public function getUsersByUsergroupAndRelation($id, $relation = 0, $order = [])
818
    {
819
        $relation = (int) $relation;
820
        $conditions = [];
821
        if (empty($relation)) {
822
            $conditions['where'] = [
823
                'usergroup_id = ? AND (relation_type = 0 OR relation_type IS NULL OR relation_type = "")' => [$id],
824
            ];
825
        } else {
826
            $conditions['where'] = [
827
                'usergroup_id = ? AND relation_type = ?' => [$id, $relation],
828
            ];
829
        }
830
831
        if (!empty($order)) {
832
            $conditions['order'] = implode(', ', array_map(function($item) {
833
                return $item . ' ASC';
834
            }, $order));
835
        }
836
837
        $results = Database::select(
838
            'ug.user_id',
839
            "{$this->usergroup_rel_user_table} ug INNER JOIN {$this->table_user} u ON ug.user_id = u.id",
840
            $conditions
841
        );
842
843
        $array = [];
844
        if (!empty($results)) {
845
            foreach ($results as $row) {
846
                $array[] = $row['user_id'];
847
            }
848
        }
849
850
        return $array;
851
    }
852
853
    /**
854
     * Get the group list for a user.
855
     *
856
     * @param int $userId       The user ID
857
     * @param int $filterByType Optional. The type of group
858
     *
859
     * @return array
860
     */
861
    public function getUserGroupListByUser($userId, $filterByType = null)
862
    {
863
        $userId = (int) $userId;
864
        if ($this->getUseMultipleUrl()) {
865
            $urlId = api_get_current_access_url_id();
866
            $from = $this->usergroup_rel_user_table." u
867
                INNER JOIN {$this->access_url_rel_usergroup} a
868
                ON (a.usergroup_id AND u.usergroup_id)
869
                INNER JOIN {$this->table} g
870
                ON (u.usergroup_id = g.id)
871
                ";
872
            $where = ['where' => ['user_id = ? AND access_url_id = ? ' => [$userId, $urlId]]];
873
        } else {
874
            $from = $this->usergroup_rel_user_table." u
875
                INNER JOIN {$this->table} g
876
                ON (u.usergroup_id = g.id)
877
                ";
878
            $where = ['where' => ['user_id = ?' => $userId]];
879
        }
880
881
        if (null !== $filterByType) {
882
            $where['where'][' AND g.group_type = ?'] = (int) $filterByType;
883
        }
884
885
        $results = Database::select(
886
            'g.*',
887
            $from,
888
            $where
889
        );
890
        $array = [];
891
        if (!empty($results)) {
892
            foreach ($results as $row) {
893
                $array[] = $row;
894
            }
895
        }
896
897
        return $array;
898
    }
899
900
    /**
901
     * Gets the usergroup id list by user id.
902
     *
903
     * @param int $userId user id
904
     *
905
     * @return array
906
     */
907
    public function get_usergroup_by_user($userId)
908
    {
909
        $userId = (int) $userId;
910
        if ($this->getUseMultipleUrl()) {
911
            $urlId = api_get_current_access_url_id();
912
            $from = $this->usergroup_rel_user_table." u
913
                    INNER JOIN {$this->access_url_rel_usergroup} a
914
                    ON (a.usergroup_id = u.usergroup_id) ";
915
            $where = ['where' => ['user_id = ? AND access_url_id = ? ' => [$userId, $urlId]]];
916
        } else {
917
            $from = $this->usergroup_rel_user_table.' u ';
918
            $where = ['where' => ['user_id = ?' => $userId]];
919
        }
920
921
        $results = Database::select(
922
            'u.usergroup_id',
923
            $from,
924
            $where
925
        );
926
927
        $array = [];
928
        if (!empty($results)) {
929
            foreach ($results as $row) {
930
                $array[] = $row['usergroup_id'];
931
            }
932
        }
933
934
        return $array;
935
    }
936
937
    /**
938
     * Subscribes sessions to a group  (also adding the members of the group in the session and course).
939
     *
940
     * @param int   $usergroup_id          usergroup id
941
     * @param array $list                  list of session ids
942
     * @param bool  $deleteCurrentSessions Optional. Empty the session list for the usergroup (class)
943
     *
944
     * @return array List of IDs of the sessions added to the usergroup
945
     */
946
    public function subscribe_sessions_to_usergroup($usergroup_id, $list, $deleteCurrentSessions = true): array
947
    {
948
        $current_list = $this->get_sessions_by_usergroup($usergroup_id);
949
        $user_list = $this->get_users_by_usergroup($usergroup_id);
950
951
        $delete_items = $new_items = [];
952
        if (!empty($list)) {
953
            foreach ($list as $session_id) {
954
                if (SessionManager::isValidId($session_id)) {
955
                    // Only if the session IDs given are not bogus
956
                    if (!in_array($session_id, $current_list)) {
957
                        $new_items[] = $session_id;
958
                    }
959
                }
960
            }
961
        }
962
        if ($deleteCurrentSessions) {
963
            if (!empty($current_list)) {
964
                foreach ($current_list as $session_id) {
965
                    if (!in_array($session_id, $list)) {
966
                        $delete_items[] = $session_id;
967
                    }
968
                }
969
            }
970
971
            // Deleting items
972
            if (!empty($delete_items)) {
973
                $sessions = '';
974
                foreach ($delete_items as $session_id) {
975
                    if (!api_get_configuration_value('usergroup_do_not_unsubscribe_users_from_session_on_session_unsubscribe')) {
976
                        if (!empty($user_list)) {
977
                            foreach ($user_list as $user_id) {
978
                                SessionManager::unsubscribe_user_from_session($session_id, $user_id);
979
                            }
980
                        }
981
                    }
982
                    Database::delete(
983
                        $this->usergroup_rel_session_table,
984
                        ['usergroup_id = ? AND session_id = ?' => [$usergroup_id, $session_id]]
985
                    );
986
                    $sessions .= $session_id.',';
987
                }
988
                // Add event to system log
989
                Event::addEvent(
990
                    LOG_GROUP_PORTAL_SESSION_UNSUBSCRIBED,
991
                    LOG_GROUP_PORTAL_ID,
992
                    'gid: '.$usergroup_id.' - sids: '.substr($sessions, 0, -1),
993
                    api_get_utc_datetime(),
994
                    api_get_user_id()
995
                );
996
            }
997
        }
998
999
        $sessions = [];
1000
        // Adding new relationships.
1001
        if (!empty($new_items)) {
1002
            foreach ($new_items as $session_id) {
1003
                $params = ['session_id' => $session_id, 'usergroup_id' => $usergroup_id];
1004
                Database::insert($this->usergroup_rel_session_table, $params);
1005
1006
                if (!empty($user_list)) {
1007
                    SessionManager::subscribeUsersToSession(
1008
                        $session_id,
1009
                        $user_list,
1010
                        null,
1011
                        false
1012
                    );
1013
                    $sessions[] = $session_id;
1014
                }
1015
            }
1016
            // Add event to system log
1017
            Event::addEvent(
1018
                LOG_GROUP_PORTAL_SESSION_SUBSCRIBED,
1019
                LOG_GROUP_PORTAL_ID,
1020
                'gid: '.$usergroup_id.' - sids: '.implode(',', $sessions),
1021
                api_get_utc_datetime(),
1022
                api_get_user_id()
1023
            );
1024
        }
1025
1026
        return $sessions;
1027
    }
1028
1029
    /**
1030
     * Subscribes courses to a group (also adding the members of the group in the course).
1031
     *
1032
     * @param int   $usergroup_id  usergroup id
1033
     * @param array $list          list of course ids (integers)
1034
     * @param bool  $delete_groups
1035
     */
1036
    public function subscribe_courses_to_usergroup($usergroup_id, $list, $delete_groups = true)
1037
    {
1038
        $current_list = $this->get_courses_by_usergroup($usergroup_id);
1039
        $user_list = $this->get_users_by_usergroup($usergroup_id);
1040
1041
        $delete_items = $new_items = [];
1042
        if (!empty($list)) {
1043
            foreach ($list as $id) {
1044
                if (!in_array($id, $current_list)) {
1045
                    $new_items[] = $id;
1046
                }
1047
            }
1048
        }
1049
1050
        if (!empty($current_list)) {
1051
            foreach ($current_list as $id) {
1052
                if (!in_array($id, $list)) {
1053
                    $delete_items[] = $id;
1054
                }
1055
            }
1056
        }
1057
1058
        if ($delete_groups) {
1059
            $this->unsubscribe_courses_from_usergroup($usergroup_id, $delete_items);
1060
        }
1061
1062
        $courses = [];
1063
        // Adding new relationships
1064
        if (!empty($new_items)) {
1065
            foreach ($new_items as $course_id) {
1066
                $course_info = api_get_course_info_by_id($course_id);
1067
                if ($course_info) {
1068
                    if (!empty($user_list)) {
1069
                        $messageError = [];
1070
                        $messageOk = [];
1071
                        foreach ($user_list as $user_id) {
1072
                            $subscribed = CourseManager::subscribeUser(
1073
                                $user_id,
1074
                                $course_info['code'],
1075
                                STUDENT,
1076
                                0,
1077
                                0,
1078
                                true,
1079
                                false
1080
                            );
1081
                            $userInfo = api_get_user_info($user_id);
1082
                            if (!$subscribed) {
1083
                                $messageError[] = sprintf(
1084
                                    get_lang('UserXNotSubscribedToCourseX'),
1085
                                    $userInfo['complete_name_with_username'],
1086
                                    $course_info['title']
1087
                                );
1088
                            } else {
1089
                                $messageOk[] = sprintf(
1090
                                    get_lang('UserXAddedToCourseX'),
1091
                                    $userInfo['complete_name_with_username'],
1092
                                    $course_info['title']
1093
                                );
1094
                            }
1095
                        }
1096
                        if (!empty($messageError)) {
1097
                            $strMessagesError = implode('<br>', $messageError);
1098
                            Display::addFlash(
1099
                                Display::return_message(
1100
                                    $strMessagesError,
1101
                                    'error',
1102
                                    false
1103
                                )
1104
                            );
1105
                        }
1106
                        if (!empty($messageOk)) {
1107
                            $strMessagesOk = implode('<br>', $messageOk);
1108
                            Display::addFlash(
1109
                                Display::return_message(
1110
                                    $strMessagesOk,
1111
                                    'normal',
1112
                                    false
1113
                                )
1114
                            );
1115
                        }
1116
                    }
1117
                    $params = [
1118
                        'course_id' => $course_id,
1119
                        'usergroup_id' => $usergroup_id,
1120
                    ];
1121
                    Database::insert(
1122
                        $this->usergroup_rel_course_table,
1123
                        $params
1124
                    );
1125
                }
1126
                $courses[] = $course_id;
1127
            }
1128
            // Add event to system log
1129
            Event::addEvent(
1130
                LOG_GROUP_PORTAL_COURSE_SUBSCRIBED,
1131
                LOG_GROUP_PORTAL_ID,
1132
                'gid: '.$usergroup_id.' - cids: '.implode(',', $courses),
1133
                api_get_utc_datetime(),
1134
                api_get_user_id()
1135
            );
1136
        }
1137
1138
        return $courses;
1139
    }
1140
1141
    /**
1142
     * Unsubscribe a usergroup from a list of courses.
1143
     *
1144
     * @param int   $usergroup_id
1145
     * @param array $delete_items
1146
     */
1147
    public function unsubscribe_courses_from_usergroup($usergroup_id, $delete_items)
1148
    {
1149
        $courses = [];
1150
        // Deleting items.
1151
        if (!empty($delete_items)) {
1152
            $user_list = $this->get_users_by_usergroup($usergroup_id);
1153
            foreach ($delete_items as $course_id) {
1154
                $course_info = api_get_course_info_by_id($course_id);
1155
                if ($course_info) {
1156
                    if (!api_get_configuration_value('usergroup_do_not_unsubscribe_users_from_course_on_course_unsubscribe')) {
1157
                        if (!empty($user_list)) {
1158
                            foreach ($user_list as $user_id) {
1159
                                CourseManager::unsubscribe_user(
1160
                                    $user_id,
1161
                                    $course_info['code']
1162
                                );
1163
                            }
1164
                        }
1165
                    }
1166
                    Database::delete(
1167
                        $this->usergroup_rel_course_table,
1168
                        [
1169
                            'usergroup_id = ? AND course_id = ?' => [
1170
                                $usergroup_id,
1171
                                $course_id,
1172
                            ],
1173
                        ]
1174
                    );
1175
                    $courses[] = $course_id;
1176
                }
1177
            }
1178
            // Add event to system log
1179
            Event::addEvent(
1180
                LOG_GROUP_PORTAL_COURSE_UNSUBSCRIBED,
1181
                LOG_GROUP_PORTAL_ID,
1182
                'gid: '.$usergroup_id.' - cids: '.implode(',', $courses),
1183
                api_get_utc_datetime(),
1184
                api_get_user_id()
1185
            );
1186
        }
1187
1188
        return $courses;
1189
    }
1190
1191
    /**
1192
     * Unsubscribe a usergroup from a list of sessions.
1193
     *
1194
     * @param int   $groupId
1195
     * @param array $items   Session IDs to remove from the group
1196
     *
1197
     * @return array The list of session IDs that have been unsubscribed from the group
1198
     */
1199
    public function unsubscribeSessionsFromUserGroup($groupId, $items)
1200
    {
1201
        // Deleting items.
1202
        $sessions = [];
1203
        if (!empty($items)) {
1204
            $users = $this->get_users_by_usergroup($groupId);
1205
            foreach ($items as $sessionId) {
1206
                if (SessionManager::isValidId($sessionId)) {
1207
                    if (!api_get_configuration_value('usergroup_do_not_unsubscribe_users_from_session_on_session_unsubscribe')) {
1208
                        if (!empty($users)) {
1209
                            foreach ($users as $userId) {
1210
                                SessionManager::unsubscribe_user_from_session(
1211
                                    $sessionId,
1212
                                    $userId
1213
                                );
1214
                            }
1215
                        }
1216
                    }
1217
                    Database::delete(
1218
                        $this->usergroup_rel_session_table,
1219
                        [
1220
                            'usergroup_id = ? AND session_id = ?' => [
1221
                                $groupId,
1222
                                $sessionId,
1223
                            ],
1224
                        ]
1225
                    );
1226
                    $sessions[] = $sessionId;
1227
                }
1228
            }
1229
            // Add event to system log
1230
            Event::addEvent(
1231
                LOG_GROUP_PORTAL_SESSION_UNSUBSCRIBED,
1232
                LOG_GROUP_PORTAL_ID,
1233
                'gid: '.$groupId.' - sids: '.implode(',', $sessions),
1234
                api_get_utc_datetime(),
1235
                api_get_user_id()
1236
            );
1237
        }
1238
1239
        return $sessions;
1240
    }
1241
1242
    /**
1243
     * Subscribe users to a group.
1244
     *
1245
     * @param int   $usergroup_id                     usergroup id
1246
     * @param array $list                             list of user ids
1247
     * @param bool  $delete_users_not_present_in_list
1248
     * @param int   $relationType
1249
     */
1250
    public function subscribe_users_to_usergroup(
1251
        $usergroup_id,
1252
        $list,
1253
        $delete_users_not_present_in_list = true,
1254
        $relationType = 0
1255
    ) {
1256
        $current_list = $this->get_users_by_usergroup($usergroup_id);
1257
        $course_list = $this->get_courses_by_usergroup($usergroup_id);
1258
        $session_list = $this->get_sessions_by_usergroup($usergroup_id);
1259
        $session_list = array_filter($session_list);
1260
        $relationType = (int) $relationType;
1261
1262
        $delete_items = [];
1263
        $new_items = [];
1264
        if (!empty($list)) {
1265
            foreach ($list as $user_id) {
1266
                if (!in_array($user_id, $current_list)) {
1267
                    $new_items[] = $user_id;
1268
                }
1269
            }
1270
        }
1271
1272
        if (!empty($current_list)) {
1273
            foreach ($current_list as $user_id) {
1274
                if (!in_array($user_id, $list)) {
1275
                    $delete_items[] = $user_id;
1276
                }
1277
            }
1278
        }
1279
1280
        // Deleting items
1281
        if (!empty($delete_items) && $delete_users_not_present_in_list) {
1282
            foreach ($delete_items as $user_id) {
1283
                if (!api_get_configuration_value('usergroup_do_not_unsubscribe_users_from_course_nor_session_on_user_unsubscribe')) {
1284
                    // Removing courses
1285
                    if (!empty($course_list)) {
1286
                        foreach ($course_list as $course_id) {
1287
                            $course_info = api_get_course_info_by_id($course_id);
1288
                            CourseManager::unsubscribe_user($user_id, $course_info['code']);
1289
                        }
1290
                    }
1291
                    // Removing sessions
1292
                    if (!empty($session_list)) {
1293
                        foreach ($session_list as $session_id) {
1294
                            SessionManager::unsubscribe_user_from_session($session_id, $user_id);
1295
                        }
1296
                    }
1297
                }
1298
1299
                if (empty($relationType)) {
1300
                    Database::delete(
1301
                        $this->usergroup_rel_user_table,
1302
                        [
1303
                            'usergroup_id = ? AND user_id = ? AND (relation_type = "0" OR relation_type IS NULL OR relation_type = "")' => [
1304
                                $usergroup_id,
1305
                                $user_id,
1306
                            ],
1307
                        ]
1308
                    );
1309
                } else {
1310
                    Database::delete(
1311
                        $this->usergroup_rel_user_table,
1312
                        [
1313
                            'usergroup_id = ? AND user_id = ? AND relation_type = ?' => [
1314
                                $usergroup_id,
1315
                                $user_id,
1316
                                $relationType,
1317
                            ],
1318
                        ]
1319
                    );
1320
                }
1321
                // Add event to system log
1322
                Event::addEvent(
1323
                    LOG_GROUP_PORTAL_USER_UNSUBSCRIBED,
1324
                    LOG_GROUP_PORTAL_ID,
1325
                    'gid: '.$usergroup_id.' - uid: '.$user_id,
1326
                    api_get_utc_datetime(),
1327
                    api_get_user_id()
1328
                );
1329
            }
1330
        }
1331
1332
        // Adding new relationships
1333
        if (!empty($new_items)) {
1334
            // Adding sessions
1335
            if (!empty($session_list)) {
1336
                foreach ($session_list as $session_id) {
1337
                    SessionManager::subscribeUsersToSession($session_id, $new_items, null, false);
1338
                }
1339
            }
1340
1341
            foreach ($new_items as $user_id) {
1342
                // Adding courses
1343
                if (!empty($course_list)) {
1344
                    $messageError = [];
1345
                    $messageOk = [];
1346
                    foreach ($course_list as $course_id) {
1347
                        $course_info = api_get_course_info_by_id($course_id);
1348
                        $subscribed = CourseManager::subscribeUser(
1349
                            $user_id,
1350
                            $course_info['code'],
1351
                            STUDENT,
1352
                            0,
1353
                            0,
1354
                            true,
1355
                            false
1356
                        );
1357
                        $userInfo = api_get_user_info($user_id);
1358
                        if (!$subscribed) {
1359
                            $messageError[] = sprintf(
1360
                                get_lang('UserXNotSubscribedToCourseX'),
1361
                                $userInfo['complete_name_with_username'],
1362
                                $course_info['title']
1363
                            );
1364
                        } else {
1365
                            $messageOk[] = sprintf(
1366
                                get_lang('UserXAddedToCourseX'),
1367
                                $userInfo['complete_name_with_username'],
1368
                                $course_info['title']
1369
                            );
1370
                        }
1371
                    }
1372
                    if (!empty($messageError)) {
1373
                        $strMessagesError = implode('<br>', $messageError);
1374
                        Display::addFlash(
1375
                            Display::return_message(
1376
                                $strMessagesError,
1377
                                'error',
1378
                                false
1379
                            )
1380
                        );
1381
                    }
1382
                    if (!empty($messageOk)) {
1383
                        $strMessagesOk = implode('<br>', $messageOk);
1384
                        Display::addFlash(
1385
                            Display::return_message(
1386
                                $strMessagesOk,
1387
                                'normal',
1388
                                false
1389
                            )
1390
                        );
1391
                    }
1392
                }
1393
                $params = [
1394
                    'user_id' => $user_id,
1395
                    'usergroup_id' => $usergroup_id,
1396
                    'relation_type' => $relationType,
1397
                ];
1398
                Database::insert($this->usergroup_rel_user_table, $params);
1399
                // Add event to system log
1400
                Event::addEvent(
1401
                    LOG_GROUP_PORTAL_USER_SUBSCRIBED,
1402
                    LOG_GROUP_PORTAL_ID,
1403
                    'gid: '.$usergroup_id.' - uid: '.$user_id,
1404
                    api_get_utc_datetime(),
1405
                    api_get_user_id()
1406
                );
1407
            }
1408
        }
1409
    }
1410
1411
    /**
1412
     * @param string $name
1413
     *
1414
     * @return bool
1415
     */
1416
    public function usergroup_exists($name)
1417
    {
1418
        $name = Database::escape_string($name);
1419
        if ($this->getUseMultipleUrl()) {
1420
            $urlId = api_get_current_access_url_id();
1421
            $sql = "SELECT * FROM $this->table u
1422
                    INNER JOIN {$this->access_url_rel_usergroup} a
1423
                    ON (a.usergroup_id = u.id)
1424
                    WHERE name = '".$name."' AND access_url_id = $urlId";
1425
        } else {
1426
            $sql = "SELECT * FROM $this->table WHERE name = '".$name."'";
1427
        }
1428
1429
        $res = Database::query($sql);
1430
1431
        return 0 != Database::num_rows($res);
1432
    }
1433
1434
    /**
1435
     * Returns whether teachers can access the classes, as per 'allow_teachers_to_classes' setting.
1436
     *
1437
     * @return bool
1438
     */
1439
    public function allowTeachers()
1440
    {
1441
        return true === api_get_configuration_value('allow_teachers_to_classes');
1442
    }
1443
1444
    /**
1445
     * @param int    $sidx
1446
     * @param int    $sord
1447
     * @param int    $start
1448
     * @param int    $limit
1449
     * @param string $extraWhereCondition
1450
     *
1451
     * @return array
1452
     */
1453
    public function getUsergroupsPagination($sidx, $sord, $start, $limit, $extraWhereCondition = '')
1454
    {
1455
        $sord = in_array(strtolower($sord), ['asc', 'desc']) ? $sord : 'desc';
1456
1457
        $start = (int) $start;
1458
        $limit = (int) $limit;
1459
1460
        $sqlFrom = "{$this->table} u ";
1461
        $sqlWhere = '1 = 1 ';
1462
1463
        if ($this->getUseMultipleUrl()) {
1464
            $urlId = api_get_current_access_url_id();
1465
            $sqlFrom .= " INNER JOIN {$this->access_url_rel_usergroup} a ON (u.id = a.usergroup_id) ";
1466
            $sqlWhere .= " AND a.access_url_id = $urlId ";
1467
        }
1468
1469
        if ($this->allowTeachers()) {
1470
            if (!api_is_platform_admin()) {
1471
                $userId = api_get_user_id();
1472
                $sqlWhere .= " AND author_id = $userId ";
1473
            }
1474
        }
1475
1476
        if ($extraWhereCondition) {
1477
            $sqlWhere .= " AND $extraWhereCondition ";
1478
        }
1479
1480
        $result = Database::store_result(
1481
            Database::query("SELECT u.* FROM $sqlFrom WHERE $sqlWhere ORDER BY name $sord LIMIT $start, $limit")
1482
        );
1483
1484
        $new_result = [];
1485
        if (!empty($result)) {
1486
            foreach ($result as $group) {
1487
                $group['sessions'] = count($this->get_sessions_by_usergroup($group['id']));
1488
                $group['courses'] = count($this->get_courses_by_usergroup($group['id']));
1489
                $roles = [];
1490
                switch ($group['group_type']) {
1491
                    case 0:
1492
                        $group['group_type'] = Display::label(get_lang('Class'), 'info');
1493
                        $roles = [0];
1494
                        break;
1495
                    case 1:
1496
                        $group['group_type'] = Display::label(get_lang('Social'), 'success');
1497
                        $roles = [
1498
                            GROUP_USER_PERMISSION_ADMIN,
1499
                            GROUP_USER_PERMISSION_READER,
1500
                            GROUP_USER_PERMISSION_MODERATOR,
1501
                            GROUP_USER_PERMISSION_HRM,
1502
                        ];
1503
                        break;
1504
                }
1505
                $group['users'] = Display::url(
1506
                    count($this->get_users_by_usergroup($group['id'], $roles)),
1507
                    api_get_path(WEB_CODE_PATH).'admin/usergroup_users.php?id='.$group['id']
1508
                );
1509
                $new_result[] = $group;
1510
            }
1511
            $result = $new_result;
1512
        }
1513
        $columns = ['name', 'users', 'courses', 'sessions', 'group_type'];
1514
1515
        if (!in_array($sidx, $columns)) {
1516
            $sidx = 'name';
1517
        }
1518
1519
        // Multidimensional sort
1520
        $result = msort($result, $sidx, $sord);
1521
1522
        return $result;
1523
    }
1524
1525
    /**
1526
     * @param array $options
1527
     *
1528
     * @return array
1529
     */
1530
    public function getDataToExport($options = [])
1531
    {
1532
        $and = '';
1533
        if (!empty($options) && !empty($options['where'])) {
1534
            $and = ' AND ';
1535
        }
1536
        if ($this->getUseMultipleUrl()) {
1537
            $urlId = api_get_current_access_url_id();
1538
            $from = $this->table." u
1539
                    INNER JOIN {$this->access_url_rel_usergroup} a
1540
                    ON (u.id = a.usergroup_id)";
1541
            $options['where'][$and.' access_url_id = ? '] = $urlId;
1542
            if ($this->allowTeachers()) {
1543
                $options['where'] = [' AND author_id = ? ' => api_get_user_id()];
1544
            }
1545
            $classes = Database::select('u.id, name, description, group_type, visibility', $from, $options);
1546
        } else {
1547
            if ($this->allowTeachers()) {
1548
                $options['where'] = [$and.' author_id = ? ' => api_get_user_id()];
1549
            }
1550
            $classes = Database::select('id, name, description, group_type, visibility', $this->table, $options);
1551
        }
1552
1553
        $result = [];
1554
        if (!empty($classes)) {
1555
            foreach ($classes as $data) {
1556
                $users = $this->getUserListByUserGroup($data['id']);
1557
                $userToString = null;
1558
                if (!empty($users)) {
1559
                    $userNameList = [];
1560
                    foreach ($users as $userData) {
1561
                        $userNameList[] = $userData['username'];
1562
                    }
1563
                    $userToString = implode(',', $userNameList);
1564
                }
1565
1566
                $courses = $this->get_courses_by_usergroup($data['id'], true);
1567
                $coursesToString = '';
1568
                if (!empty($courses)) {
1569
                    $coursesToString = implode(', ', array_column($courses, 'code'));
1570
                }
1571
1572
                $sessions = $this->get_sessions_by_usergroup($data['id']);
1573
                $sessionsToString = '';
1574
                if (!empty($sessions)) {
1575
                    $sessionList = [];
1576
                    foreach ($sessions as $sessionId) {
1577
                        $sessionList[] = api_get_session_info($sessionId)['name'];
1578
                    }
1579
                    $sessionsToString = implode(', ', $sessionList);
1580
                }
1581
1582
                $data['users'] = $userToString;
1583
                $data['courses'] = $coursesToString;
1584
                $data['sessions'] = $sessionsToString;
1585
                $result[] = $data;
1586
            }
1587
        }
1588
1589
        return $result;
1590
    }
1591
1592
    /**
1593
     * @param string $firstLetter
1594
     * @param int    $limit
1595
     *
1596
     * @return array
1597
     */
1598
    public function filterByFirstLetter($firstLetter, $limit = 0)
1599
    {
1600
        $firstLetter = Database::escape_string($firstLetter);
1601
        $limit = (int) $limit;
1602
1603
        $sql = ' SELECT g.id, name ';
1604
1605
        $urlCondition = '';
1606
        if ($this->getUseMultipleUrl()) {
1607
            $urlId = api_get_current_access_url_id();
1608
            $sql .= " FROM $this->table g
1609
                    INNER JOIN $this->access_url_rel_usergroup a
1610
                    ON (g.id = a.usergroup_id) ";
1611
            $urlCondition = " AND access_url_id = $urlId ";
1612
        } else {
1613
            $sql = " FROM $this->table g ";
1614
        }
1615
        $sql .= "
1616
		        WHERE
1617
		            name LIKE '".$firstLetter."%' OR
1618
		            name LIKE '".api_strtolower($firstLetter)."%'
1619
		            $urlCondition
1620
		        ORDER BY name DESC ";
1621
1622
        if (!empty($limit)) {
1623
            $sql .= " LIMIT $limit ";
1624
        }
1625
1626
        $result = Database::query($sql);
1627
1628
        return Database::store_result($result);
1629
    }
1630
1631
    /**
1632
     * Select user group not in list.
1633
     *
1634
     * @param array $list
1635
     *
1636
     * @return array
1637
     */
1638
    public function getUserGroupNotInList($list)
1639
    {
1640
        if (empty($list)) {
1641
            return [];
1642
        }
1643
1644
        $list = array_map('intval', $list);
1645
        $listToString = implode("','", $list);
1646
        $sql = "SELECT * FROM $this->table g WHERE g.id NOT IN ('$listToString')";
1647
        $result = Database::query($sql);
1648
1649
        return Database::store_result($result, 'ASSOC');
1650
    }
1651
1652
    /**
1653
     * @param $params
1654
     * @param bool $show_query
1655
     *
1656
     * @return bool|int
1657
     */
1658
    public function save($params, $show_query = false)
1659
    {
1660
        $params['updated_at'] = $params['created_at'] = api_get_utc_datetime();
1661
        $params['group_type'] = !empty($params['group_type']) ? self::SOCIAL_CLASS : self::NORMAL_CLASS;
1662
        $params['allow_members_leave_group'] = isset($params['allow_members_leave_group']) ? 1 : 0;
1663
1664
        $groupExists = $this->usergroup_exists(trim($params['name']));
1665
        if (false == $groupExists) {
1666
            if ($this->allowTeachers()) {
1667
                $params['author_id'] = api_get_user_id();
1668
            }
1669
            $id = parent::save($params, $show_query);
1670
            if ($id) {
1671
                if ($this->getUseMultipleUrl()) {
1672
                    $this->subscribeToUrl($id, api_get_current_access_url_id());
1673
                }
1674
1675
                if (self::SOCIAL_CLASS == $params['group_type']) {
1676
                    $this->add_user_to_group(
1677
                        api_get_user_id(),
1678
                        $id,
1679
                        GROUP_USER_PERMISSION_ADMIN
1680
                    );
1681
                }
1682
                $picture = isset($_FILES['picture']) ? $_FILES['picture'] : null;
1683
                $picture = $this->manageFileUpload($id, $picture);
1684
                if ($picture) {
1685
                    $params = [
1686
                        'id' => $id,
1687
                        'picture' => $picture,
1688
                        'group_type' => $params['group_type'],
1689
                    ];
1690
                    $this->update($params);
1691
                }
1692
            }
1693
            // Add event to system log
1694
            Event::addEvent(
1695
                LOG_GROUP_PORTAL_CREATED,
1696
                LOG_GROUP_PORTAL_ID,
1697
                'id: '.$id,
1698
                api_get_utc_datetime(),
1699
                api_get_user_id()
1700
            );
1701
1702
            return $id;
1703
        }
1704
1705
        return false;
1706
    }
1707
1708
    /**
1709
     * {@inheritdoc}
1710
     */
1711
    public function update($values, $showQuery = false)
1712
    {
1713
        $values['updated_on'] = api_get_utc_datetime();
1714
        $values['group_type'] = !empty($values['group_type']) ? self::SOCIAL_CLASS : self::NORMAL_CLASS;
1715
        $values['allow_members_leave_group'] = isset($values['allow_members_leave_group']) ? 1 : 0;
1716
1717
        if (isset($values['id'])) {
1718
            $picture = isset($_FILES['picture']) ? $_FILES['picture'] : null;
1719
            if (!empty($picture)) {
1720
                $picture = $this->manageFileUpload($values['id'], $picture);
1721
                if ($picture) {
1722
                    $values['picture'] = $picture;
1723
                }
1724
            }
1725
1726
            if (isset($values['delete_picture'])) {
1727
                $values['picture'] = null;
1728
            }
1729
        }
1730
1731
        parent::update($values, $showQuery);
1732
1733
        if (isset($values['delete_picture'])) {
1734
            $this->delete_group_picture($values['id']);
1735
        }
1736
        // Add event to system log
1737
        Event::addEvent(
1738
            LOG_GROUP_PORTAL_UPDATED,
1739
            LOG_GROUP_PORTAL_ID,
1740
            'id: '.$values['id'],
1741
            api_get_utc_datetime(),
1742
            api_get_user_id()
1743
        );
1744
1745
        return true;
1746
    }
1747
1748
    /**
1749
     * @param int    $groupId
1750
     * @param string $picture
1751
     *
1752
     * @return bool|string
1753
     */
1754
    public function manageFileUpload($groupId, $picture)
1755
    {
1756
        if (!empty($picture['name'])) {
1757
            return $this->update_group_picture(
1758
                $groupId,
1759
                $picture['name'],
1760
                $picture['tmp_name']
1761
            );
1762
        }
1763
1764
        return false;
1765
    }
1766
1767
    /**
1768
     * @param int $groupId
1769
     *
1770
     * @return string
1771
     */
1772
    public function delete_group_picture($groupId)
1773
    {
1774
        return $this->update_group_picture($groupId);
1775
    }
1776
1777
    /**
1778
     * Creates new group pictures in various sizes of a user, or deletes user pfotos.
1779
     * Note: This method relies on configuration setting from main/inc/conf/profile.conf.php.
1780
     *
1781
     * @param    int    The group id
1782
     * @param string $file The common file name for the newly created photos.
1783
     *                     It will be checked and modified for compatibility with the file system.
1784
     *                     If full name is provided, path component is ignored.
1785
     *                     If an empty name is provided, then old user photos are deleted only,
1786
     *
1787
     * @see UserManager::delete_user_picture() as the prefered way for deletion.
1788
     *
1789
     * @param string $source_file the full system name of the image from which user photos will be created
1790
     *
1791
     * @return mixed Returns the resulting common file name of created images which usually should be stored in database.
1792
     *               When an image is removed the function returns an empty string.
1793
     *               In case of internal error or negative validation it returns FALSE.
1794
     */
1795
    public function update_group_picture($group_id, $file = null, $source_file = null)
1796
    {
1797
        $group_id = (int) $group_id;
1798
1799
        if (empty($group_id)) {
1800
            return false;
1801
        }
1802
        $delete = empty($file);
1803
        if (empty($source_file)) {
1804
            $source_file = $file;
1805
        }
1806
1807
        // User-reserved directory where photos have to be placed.
1808
        $path_info = $this->get_group_picture_path_by_id($group_id, 'system', true);
1809
1810
        $path = $path_info['dir'];
1811
1812
        // If this directory does not exist - we create it.
1813
        if (!is_dir($path)) {
1814
            $res = @mkdir($path, api_get_permissions_for_new_directories(), true);
1815
            if ($res === false) {
1816
                // There was an issue creating the directory $path, probably
1817
                // permissions-related
1818
                return false;
1819
            }
1820
        }
1821
1822
        // The old photos (if any).
1823
        $old_file = $path_info['file'];
1824
1825
        // Let us delete them.
1826
        if (!empty($old_file)) {
1827
            if (KEEP_THE_OLD_IMAGE_AFTER_CHANGE) {
1828
                $prefix = 'saved_'.date('Y_m_d_H_i_s').'_'.uniqid('').'_';
1829
                @rename($path.'small_'.$old_file, $path.$prefix.'small_'.$old_file);
1830
                @rename($path.'medium_'.$old_file, $path.$prefix.'medium_'.$old_file);
1831
                @rename($path.'big_'.$old_file, $path.$prefix.'big_'.$old_file);
1832
                @rename($path.$old_file, $path.$prefix.$old_file);
1833
            } else {
1834
                @unlink($path.'small_'.$old_file);
1835
                @unlink($path.'medium_'.$old_file);
1836
                @unlink($path.'big_'.$old_file);
1837
                @unlink($path.$old_file);
1838
            }
1839
        }
1840
1841
        // Exit if only deletion has been requested. Return an empty picture name.
1842
        if ($delete) {
1843
            return '';
1844
        }
1845
1846
        // Validation 2.
1847
        $allowed_types = ['jpg', 'jpeg', 'png', 'gif'];
1848
        $file = str_replace('\\', '/', $file);
1849
        $filename = (($pos = strrpos($file, '/')) !== false) ? substr($file, $pos + 1) : $file;
1850
        $extension = strtolower(substr(strrchr($filename, '.'), 1));
1851
        if (!in_array($extension, $allowed_types)) {
1852
            return false;
1853
        }
1854
1855
        // This is the common name for the new photos.
1856
        if (KEEP_THE_NAME_WHEN_CHANGE_IMAGE && !empty($old_file)) {
1857
            $old_extension = strtolower(substr(strrchr($old_file, '.'), 1));
1858
            $filename = in_array($old_extension, $allowed_types) ? substr($old_file, 0, -strlen($old_extension)) : $old_file;
1859
            $filename = (substr($filename, -1) == '.') ? $filename.$extension : $filename.'.'.$extension;
1860
        } else {
1861
            $filename = api_replace_dangerous_char($filename);
1862
            if (PREFIX_IMAGE_FILENAME_WITH_UID) {
1863
                $filename = uniqid('').'_'.$filename;
1864
            }
1865
            // We always prefix user photos with user ids, so on setting
1866
            // api_get_setting('split_users_upload_directory') === 'true'
1867
            // the correspondent directories to be found successfully.
1868
            $filename = $group_id.'_'.$filename;
1869
        }
1870
1871
        // Storing the new photos in 4 versions with various sizes.
1872
1873
        /*$image->resize(
1874
        // get original size and set width (widen) or height (heighten).
1875
        // width or height will be set maintaining aspect ratio.
1876
            $image->getSize()->widen( 700 )
1877
        );*/
1878
1879
        // Usign the Imagine service
1880
        $imagine = new Imagine\Gd\Imagine();
1881
        $image = $imagine->open($source_file);
1882
1883
        $options = [
1884
            'quality' => 90,
1885
        ];
1886
1887
        //$image->resize(new Imagine\Image\Box(200, 200))->save($path.'big_'.$filename);
1888
        $image->resize($image->getSize()->widen(200))->save($path.'big_'.$filename, $options);
1889
1890
        $image = $imagine->open($source_file);
1891
        $image->resize(new Imagine\Image\Box(85, 85))->save($path.'medium_'.$filename, $options);
1892
1893
        $image = $imagine->open($source_file);
1894
        $image->resize(new Imagine\Image\Box(22, 22))->save($path.'small_'.$filename);
1895
1896
        /*
1897
        $small  = self::resize_picture($source_file, 22);
1898
        $medium = self::resize_picture($source_file, 85);
1899
        $normal = self::resize_picture($source_file, 200);
1900
1901
        $big = new Image($source_file); // This is the original picture.
1902
        $ok = $small && $small->send_image($path.'small_'.$filename)
1903
            && $medium && $medium->send_image($path.'medium_'.$filename)
1904
            && $normal && $normal->send_image($path.'big_'.$filename)
1905
            && $big && $big->send_image($path.$filename);
1906
        return $ok ? $filename : false;*/
1907
        return $filename;
1908
    }
1909
1910
    /**
1911
     * @return mixed
1912
     */
1913
    public function getGroupType()
1914
    {
1915
        return $this->groupType;
1916
    }
1917
1918
    /**
1919
     * @param int $id
1920
     *
1921
     * @return bool|void
1922
     */
1923
    public function delete($id)
1924
    {
1925
        $id = (int) $id;
1926
        if ($this->getUseMultipleUrl()) {
1927
            $this->unsubscribeToUrl($id, api_get_current_access_url_id());
1928
        }
1929
1930
        $sql = "DELETE FROM $this->usergroup_rel_user_table
1931
                WHERE usergroup_id = $id";
1932
        Database::query($sql);
1933
1934
        $sql = "DELETE FROM $this->usergroup_rel_course_table
1935
                WHERE usergroup_id = $id";
1936
        Database::query($sql);
1937
1938
        $sql = "DELETE FROM $this->usergroup_rel_session_table
1939
                WHERE usergroup_id = $id";
1940
        Database::query($sql);
1941
1942
        $res = parent::delete($id);
1943
        // Add event to system log
1944
        if ($res) {
1945
            Event::addEvent(
1946
                LOG_GROUP_PORTAL_DELETED,
1947
                LOG_GROUP_PORTAL_ID,
1948
                'id: '.$id,
1949
                api_get_utc_datetime(),
1950
                api_get_user_id()
1951
            );
1952
        }
1953
1954
        return $res;
1955
    }
1956
1957
    /**
1958
     * @param int $id
1959
     * @param int $urlId
1960
     */
1961
    public function subscribeToUrl($id, $urlId)
1962
    {
1963
        Database::insert(
1964
            $this->access_url_rel_usergroup,
1965
            [
1966
                'access_url_id' => $urlId,
1967
                'usergroup_id' => $id,
1968
            ]
1969
        );
1970
    }
1971
1972
    /**
1973
     * @param int $id
1974
     * @param int $urlId
1975
     */
1976
    public function unsubscribeToUrl($id, $urlId)
1977
    {
1978
        Database::delete(
1979
            $this->access_url_rel_usergroup,
1980
            [
1981
                'access_url_id = ? AND usergroup_id = ? ' => [$urlId, $id],
1982
            ]
1983
        );
1984
    }
1985
1986
    /**
1987
     * @param $needle
1988
     *
1989
     * @return xajaxResponse
1990
     */
1991
    public static function searchUserGroupAjax($needle)
1992
    {
1993
        $response = new xajaxResponse();
1994
        $return = '';
1995
1996
        if (!empty($needle)) {
1997
            // xajax send utf8 datas... datas in db can be non-utf8 datas
1998
            $charset = api_get_system_encoding();
1999
            $needle = api_convert_encoding($needle, $charset, 'utf-8');
2000
            $needle = Database::escape_string($needle);
2001
2002
            $sql = 'SELECT id, name
2003
                    FROM '.Database::get_main_table(TABLE_USERGROUP).' u
2004
                    WHERE name LIKE "'.$needle.'%"
2005
                    ORDER BY name
2006
                    LIMIT 11';
2007
            $result = Database::query($sql);
2008
            $i = 0;
2009
            while ($data = Database::fetch_array($result)) {
2010
                $i++;
2011
                if ($i <= 10) {
2012
                    $return .= '<a
2013
                    href="javascript: void(0);"
2014
                    onclick="javascript: add_user_to_url(\''.addslashes($data['id']).'\',\''.addslashes($data['name']).' \')">'.$data['name'].' </a><br />';
2015
                } else {
2016
                    $return .= '...<br />';
2017
                }
2018
            }
2019
        }
2020
        $response->addAssign('ajax_list_courses', 'innerHTML', api_utf8_encode($return));
2021
2022
        return $response;
2023
    }
2024
2025
    /**
2026
     * Get user list by usergroup.
2027
     *
2028
     * @param int    $id
2029
     * @param string $orderBy
2030
     *
2031
     * @return array
2032
     */
2033
    public function getUserListByUserGroup($id, $orderBy = '')
2034
    {
2035
        $id = (int) $id;
2036
        $sql = "SELECT u.* FROM $this->table_user u
2037
                INNER JOIN $this->usergroup_rel_user_table c
2038
                ON c.user_id = u.id
2039
                WHERE c.usergroup_id = $id"
2040
                ;
2041
2042
        if (!empty($orderBy)) {
2043
            $orderBy = Database::escape_string($orderBy);
2044
            $sql .= " ORDER BY $orderBy ";
2045
        }
2046
        $result = Database::query($sql);
2047
2048
        return Database::store_result($result);
2049
    }
2050
2051
    /**
2052
     * @param FormValidator $form
2053
     * @param string        $type
2054
     * @param array         $data
2055
     */
2056
    public function setForm($form, $type = 'add', $data = [])
2057
    {
2058
        $header = '';
2059
        switch ($type) {
2060
            case 'add':
2061
                $header = get_lang('Add');
2062
                break;
2063
            case 'edit':
2064
                $header = get_lang('Edit');
2065
                break;
2066
        }
2067
2068
        $form->addHeader($header);
2069
2070
        // Name
2071
        $form->addText('name', get_lang('Name'), true, ['maxlength' => 255]);
2072
        $form->addRule('name', '', 'maxlength', 255);
2073
2074
        // Description
2075
        $form->addTextarea('description', get_lang('Description'), ['cols' => 58]);
2076
        $form->applyFilter('description', 'trim');
2077
2078
        if ($this->showGroupTypeSetting) {
2079
            $form->addElement(
2080
                'checkbox',
2081
                'group_type',
2082
                null,
2083
                get_lang('SocialGroup')
2084
            );
2085
        }
2086
2087
        // url
2088
        $form->addText('url', get_lang('Url'), false);
2089
2090
        // Picture
2091
        $allowed_picture_types = $this->getAllowedPictureExtensions();
2092
2093
        $form->addFile('picture', get_lang('AddPicture'));
2094
        $form->addRule(
2095
            'picture',
2096
            get_lang('OnlyImagesAllowed').' ('.implode(',', $allowed_picture_types).')',
2097
            'filetype',
2098
            $allowed_picture_types
2099
        );
2100
2101
        if (isset($data['picture']) && strlen($data['picture']) > 0) {
2102
            $picture = $this->get_picture_group($data['id'], $data['picture'], 80);
2103
            $img = '<img src="'.$picture['file'].'" />';
2104
            $form->addLabel(null, $img);
2105
            $form->addElement('checkbox', 'delete_picture', '', get_lang('DelImage'));
2106
        }
2107
2108
        $form->addElement('select', 'visibility', get_lang('GroupPermissions'), $this->getGroupStatusList());
2109
        $form->setRequiredNote('<span class="form_required">*</span> <small>'.get_lang('ThisFieldIsRequired').'</small>');
2110
        $form->addElement('checkbox', 'allow_members_leave_group', '', get_lang('AllowMemberLeaveGroup'));
2111
2112
        // Setting the form elements
2113
        if ($type === 'add') {
2114
            $form->addButtonCreate($header);
2115
        } else {
2116
            $form->addButtonUpdate($header);
2117
        }
2118
    }
2119
2120
    /**
2121
     * Gets the current group image.
2122
     *
2123
     * @param string $id group id
2124
     * @param string picture group name
2125
     * @param string height
2126
     * @param string $size_picture picture size it can be small_,  medium_  or  big_
2127
     * @param string style css
2128
     *
2129
     * @return array with the file and the style of an image i.e $array['file'] $array['style']
2130
     */
2131
    public function get_picture_group(
2132
        $id,
2133
        $picture_file,
2134
        $height,
2135
        $size_picture = GROUP_IMAGE_SIZE_MEDIUM,
2136
        $style = ''
2137
    ) {
2138
        $picture = [];
2139
        if ($picture_file === 'unknown.jpg') {
2140
            $picture['file'] = Display::returnIconPath($picture_file);
2141
2142
            return $picture;
2143
        }
2144
2145
        switch ($size_picture) {
2146
            case GROUP_IMAGE_SIZE_ORIGINAL:
2147
                $size_picture = '';
2148
                break;
2149
            case GROUP_IMAGE_SIZE_BIG:
2150
                $size_picture = 'big_';
2151
                break;
2152
            case GROUP_IMAGE_SIZE_MEDIUM:
2153
                $size_picture = 'medium_';
2154
                break;
2155
            case GROUP_IMAGE_SIZE_SMALL:
2156
                $size_picture = 'small_';
2157
                break;
2158
            default:
2159
                $size_picture = 'medium_';
2160
        }
2161
2162
        $image_array_sys = $this->get_group_picture_path_by_id($id, 'system', false, true);
2163
        $image_array = $this->get_group_picture_path_by_id($id, 'web', false, true);
2164
        $file = $image_array_sys['dir'].$size_picture.$picture_file;
2165
        if (file_exists($file)) {
2166
            $picture['file'] = $image_array['dir'].$size_picture.$picture_file;
2167
            if ($height > 0) {
2168
                $dimension = api_getimagesize($picture['file']);
2169
                $margin = ($height - $dimension['width']) / 2;
2170
                //@ todo the padding-top should not be here
2171
            }
2172
        } else {
2173
            $file = $image_array_sys['dir'].$picture_file;
2174
            if (file_exists($file) && !is_dir($file)) {
2175
                $picture['file'] = $image_array['dir'].$picture_file;
2176
            } else {
2177
                $picture['file'] = Display::returnIconPath('group_na.png', 64);
2178
            }
2179
        }
2180
2181
        return $picture;
2182
    }
2183
2184
    /**
2185
     * Gets the group picture URL or path from group ID (returns an array).
2186
     * The return format is a complete path, enabling recovery of the directory
2187
     * with dirname() or the file with basename(). This also works for the
2188
     * functions dealing with the user's productions, as they are located in
2189
     * the same directory.
2190
     *
2191
     * @param    int    User ID
2192
     * @param    string    Type of path to return (can be 'none', 'system', 'rel', 'web')
2193
     * @param    bool    Whether we want to have the directory name returned 'as if'
2194
     * there was a file or not (in the case we want to know which directory to create -
2195
     * otherwise no file means no split subdir)
2196
     * @param    bool    If we want that the function returns the /main/img/unknown.jpg image set it at true
2197
     *
2198
     * @return array Array of 2 elements: 'dir' and 'file' which contain the dir
2199
     *               and file as the name implies if image does not exist it will return the unknown
2200
     *               image if anonymous parameter is true if not it returns an empty er's
2201
     */
2202
    public function get_group_picture_path_by_id($id, $type = 'none', $preview = false, $anonymous = false)
2203
    {
2204
        switch ($type) {
2205
            case 'system': // Base: absolute system path.
2206
                $base = api_get_path(SYS_UPLOAD_PATH);
2207
                break;
2208
            case 'rel': // Base: semi-absolute web path (no server base).
2209
                $base = api_get_path(REL_CODE_PATH);
2210
                break;
2211
            case 'web': // Base: absolute web path.
2212
                $base = api_get_path(WEB_UPLOAD_PATH);
2213
                break;
2214
            case 'none':
2215
            default: // Base: empty, the result path below will be relative.
2216
                $base = '';
2217
        }
2218
        $id = (int) $id;
2219
2220
        if (empty($id) || empty($type)) {
2221
            return $anonymous ? ['dir' => $base.'img/', 'file' => 'unknown.jpg'] : ['dir' => '', 'file' => ''];
2222
        }
2223
2224
        $group_table = Database::get_main_table(TABLE_USERGROUP);
2225
        $sql = "SELECT picture FROM $group_table WHERE id = ".$id;
2226
        $res = Database::query($sql);
2227
2228
        if (!Database::num_rows($res)) {
2229
            return $anonymous ? ['dir' => $base.'img/', 'file' => 'unknown.jpg'] : ['dir' => '', 'file' => ''];
2230
        }
2231
        $user = Database::fetch_array($res);
2232
        $picture_filename = trim($user['picture']);
2233
2234
        if (api_get_setting('split_users_upload_directory') === 'true') {
2235
            if (!empty($picture_filename)) {
2236
                $dir = $base.'groups/'.substr($picture_filename, 0, 1).'/'.$id.'/';
2237
            } elseif ($preview) {
2238
                $dir = $base.'groups/'.substr((string) $id, 0, 1).'/'.$id.'/';
2239
            } else {
2240
                $dir = $base.'groups/'.$id.'/';
2241
            }
2242
        } else {
2243
            $dir = $base.'groups/'.$id.'/';
2244
        }
2245
2246
        return ['dir' => $dir, 'file' => $picture_filename];
2247
    }
2248
2249
    /**
2250
     * @return array
2251
     */
2252
    public function getAllowedPictureExtensions()
2253
    {
2254
        return ['jpg', 'jpeg', 'png', 'gif'];
2255
    }
2256
2257
    /**
2258
     * @return array
2259
     */
2260
    public function getGroupStatusList()
2261
    {
2262
        $status = [
2263
            GROUP_PERMISSION_OPEN => get_lang('Open'),
2264
            GROUP_PERMISSION_CLOSED => get_lang('Closed'),
2265
        ];
2266
2267
        return $status;
2268
    }
2269
2270
    /**
2271
     * @param int $type
2272
     */
2273
    public function setGroupType($type)
2274
    {
2275
        $this->groupType = (int) $type;
2276
    }
2277
2278
    /**
2279
     * @param int $group_id
2280
     * @param int $user_id
2281
     *
2282
     * @return bool
2283
     */
2284
    public function is_group_admin($group_id, $user_id = 0)
2285
    {
2286
        if (empty($user_id)) {
2287
            $user_id = api_get_user_id();
2288
        }
2289
        $user_role = $this->get_user_group_role($user_id, $group_id);
2290
        if (in_array($user_role, [GROUP_USER_PERMISSION_ADMIN])) {
2291
            return true;
2292
        } else {
2293
            return false;
2294
        }
2295
    }
2296
2297
    /**
2298
     * @param int $group_id
2299
     * @param int $user_id
2300
     *
2301
     * @return bool
2302
     */
2303
    public function isGroupModerator($group_id, $user_id = 0)
2304
    {
2305
        if (empty($user_id)) {
2306
            $user_id = api_get_user_id();
2307
        }
2308
        $user_role = $this->get_user_group_role($user_id, $group_id);
2309
        if (in_array($user_role, [GROUP_USER_PERMISSION_ADMIN, GROUP_USER_PERMISSION_MODERATOR])) {
2310
            return true;
2311
        } else {
2312
            return false;
2313
        }
2314
    }
2315
2316
    /**
2317
     * @param int $group_id
2318
     * @param int $user_id
2319
     *
2320
     * @return bool
2321
     */
2322
    public function is_group_member($group_id, $user_id = 0)
2323
    {
2324
        if (api_is_platform_admin()) {
2325
            return true;
2326
        }
2327
        if (empty($user_id)) {
2328
            $user_id = api_get_user_id();
2329
        }
2330
        $roles = [
2331
            GROUP_USER_PERMISSION_ADMIN,
2332
            GROUP_USER_PERMISSION_MODERATOR,
2333
            GROUP_USER_PERMISSION_READER,
2334
            GROUP_USER_PERMISSION_HRM,
2335
        ];
2336
        $user_role = $this->get_user_group_role($user_id, $group_id);
2337
        if (in_array($user_role, $roles)) {
2338
            return true;
2339
        } else {
2340
            return false;
2341
        }
2342
    }
2343
2344
    /**
2345
     * Gets the relationship between a group and a User.
2346
     *
2347
     * @author Julio Montoya
2348
     *
2349
     * @param int $user_id
2350
     * @param int $group_id
2351
     *
2352
     * @return int 0 if there are not relationship otherwise returns the user group
2353
     * */
2354
    public function get_user_group_role($user_id, $group_id)
2355
    {
2356
        $table_group_rel_user = $this->usergroup_rel_user_table;
2357
        $return_value = 0;
2358
        $user_id = (int) $user_id;
2359
        $group_id = (int) $group_id;
2360
2361
        if (!empty($user_id) && !empty($group_id)) {
2362
            $sql = "SELECT relation_type
2363
                    FROM $table_group_rel_user
2364
                    WHERE
2365
                        usergroup_id = $group_id AND
2366
                        user_id = $user_id ";
2367
            $result = Database::query($sql);
2368
            if (Database::num_rows($result) > 0) {
2369
                $row = Database::fetch_array($result, 'ASSOC');
2370
                $return_value = $row['relation_type'];
2371
            }
2372
        }
2373
2374
        return $return_value;
2375
    }
2376
2377
    /**
2378
     * @param int $userId
2379
     * @param int $groupId
2380
     *
2381
     * @return string
2382
     */
2383
    public function getUserRoleToString($userId, $groupId)
2384
    {
2385
        $role = $this->get_user_group_role($userId, $groupId);
2386
        $roleToString = '';
2387
2388
        switch ($role) {
2389
            case GROUP_USER_PERMISSION_ADMIN:
2390
                $roleToString = get_lang('Admin');
2391
                break;
2392
            case GROUP_USER_PERMISSION_READER:
2393
                $roleToString = get_lang('Reader');
2394
                break;
2395
            case GROUP_USER_PERMISSION_PENDING_INVITATION:
2396
                $roleToString = get_lang('PendingInvitation');
2397
                break;
2398
            case GROUP_USER_PERMISSION_MODERATOR:
2399
                $roleToString = get_lang('Moderator');
2400
                break;
2401
            case GROUP_USER_PERMISSION_HRM:
2402
                $roleToString = get_lang('Drh');
2403
                break;
2404
        }
2405
2406
        return $roleToString;
2407
    }
2408
2409
    /**
2410
     * Add a group of users into a group of URLs.
2411
     *
2412
     * @author Julio Montoya
2413
     *
2414
     * @param array $user_list
2415
     * @param array $group_list
2416
     * @param int   $relation_type
2417
     *
2418
     * @return array
2419
     */
2420
    public function add_users_to_groups($user_list, $group_list, $relation_type = GROUP_USER_PERMISSION_READER)
2421
    {
2422
        $table_url_rel_group = $this->usergroup_rel_user_table;
2423
        $result_array = [];
2424
        $relation_type = (int) $relation_type;
2425
2426
        if (is_array($user_list) && is_array($group_list)) {
2427
            foreach ($group_list as $group_id) {
2428
                $usersList = '';
2429
                foreach ($user_list as $user_id) {
2430
                    $user_id = (int) $user_id;
2431
                    $group_id = (int) $group_id;
2432
2433
                    $role = $this->get_user_group_role($user_id, $group_id);
2434
                    if ($role == 0) {
2435
                        $sql = "INSERT INTO $table_url_rel_group
2436
		               			SET
2437
		               			    user_id = $user_id ,
2438
		               			    usergroup_id = $group_id ,
2439
		               			    relation_type = $relation_type ";
2440
2441
                        $result = Database::query($sql);
2442
                        if ($result) {
2443
                            $result_array[$group_id][$user_id] = 1;
2444
                        } else {
2445
                            $result_array[$group_id][$user_id] = 0;
2446
                        }
2447
                    }
2448
                    $usersList .= $user_id.',';
2449
                }
2450
                // Add event to system log
2451
                Event::addEvent(
2452
                    LOG_GROUP_PORTAL_USER_SUBSCRIBED,
2453
                    LOG_GROUP_PORTAL_ID,
2454
                    'gid: '.$group_id.' - uids: '.substr($usersList, 0, -1),
2455
                    api_get_utc_datetime(),
2456
                    api_get_user_id()
2457
                );
2458
            }
2459
        }
2460
2461
        return $result_array;
2462
    }
2463
2464
    /**
2465
     * Deletes the subscription of a user to a usergroup.
2466
     *
2467
     * @author Julio Montoya
2468
     *
2469
     * @param int $userId
2470
     * @param int $groupId
2471
     *
2472
     * @return bool true on success
2473
     * */
2474
    public function delete_user_rel_group($userId, $groupId)
2475
    {
2476
        $userId = (int) $userId;
2477
        $groupId = (int) $groupId;
2478
        if (empty($userId) || empty($groupId)) {
2479
            return false;
2480
        }
2481
2482
        $table = $this->usergroup_rel_user_table;
2483
        $sql = "DELETE FROM $table
2484
                WHERE
2485
                    user_id = $userId AND
2486
                    usergroup_id = $groupId";
2487
2488
        $result = Database::query($sql);
2489
        // Add event to system log
2490
        Event::addEvent(
2491
            LOG_GROUP_PORTAL_USER_UNSUBSCRIBED,
2492
            LOG_GROUP_PORTAL_ID,
2493
            'gid: '.$groupId.' - uid: '.$userId,
2494
            api_get_utc_datetime(),
2495
            api_get_user_id()
2496
        );
2497
2498
        return $result;
2499
    }
2500
2501
    /**
2502
     * Add a user into a group.
2503
     *
2504
     * @author Julio Montoya
2505
     *
2506
     * @param int $user_id
2507
     * @param int $group_id
2508
     * @param int $relation_type
2509
     *
2510
     * @return bool true if success
2511
     */
2512
    public function add_user_to_group($user_id, $group_id, $relation_type = GROUP_USER_PERMISSION_READER)
2513
    {
2514
        $table_url_rel_group = $this->usergroup_rel_user_table;
2515
        $user_id = (int) $user_id;
2516
        $group_id = (int) $group_id;
2517
        $relation_type = (int) $relation_type;
2518
        // Temporary hack to avoid issues with roles - see #4980
2519
        if ($relation_type == GROUP_USER_PERMISSION_READER) {
2520
            $relation_type = 0;
2521
        }
2522
        if (!empty($user_id) && !empty($group_id)) {
2523
            $role = $this->get_user_group_role($user_id, $group_id);
2524
2525
            if ($role == 0) {
2526
                $sql = "INSERT INTO $table_url_rel_group
2527
           				SET
2528
           				    user_id = ".$user_id.",
2529
           				    usergroup_id = ".$group_id.",
2530
           				    relation_type = ".$relation_type;
2531
                Database::query($sql);
2532
                // Add event to system log
2533
                Event::addEvent(
2534
                    LOG_GROUP_PORTAL_USER_SUBSCRIBED,
2535
                    LOG_GROUP_PORTAL_ID,
2536
                    'gid: '.$group_id.' - uid: '.$user_id,
2537
                    api_get_utc_datetime(),
2538
                    api_get_user_id()
2539
                );
2540
            } elseif ($role == GROUP_USER_PERMISSION_PENDING_INVITATION) {
2541
                //if somebody already invited me I can be added
2542
                self::update_user_role($user_id, $group_id, GROUP_USER_PERMISSION_READER);
2543
            }
2544
        }
2545
2546
        return true;
2547
    }
2548
2549
    /**
2550
     * Updates the group_rel_user table  with a given user and group ids.
2551
     *
2552
     * @author Julio Montoya
2553
     *
2554
     * @param int $user_id
2555
     * @param int $group_id
2556
     * @param int $relation_type
2557
     */
2558
    public function update_user_role($user_id, $group_id, $relation_type = GROUP_USER_PERMISSION_READER)
2559
    {
2560
        $table_group_rel_user = $this->usergroup_rel_user_table;
2561
        $group_id = (int) $group_id;
2562
        $user_id = (int) $user_id;
2563
        $relation_type = (int) $relation_type;
2564
2565
        $sql = "UPDATE $table_group_rel_user
2566
   				SET relation_type = $relation_type
2567
                WHERE user_id = $user_id AND usergroup_id = $group_id";
2568
        Database::query($sql);
2569
    }
2570
2571
    /**
2572
     * Gets the inner join from users and group table.
2573
     *
2574
     * @return array Database::store_result of the result
2575
     *
2576
     * @author Julio Montoya
2577
     * */
2578
    public function get_groups_by_user($user_id, $relationType = GROUP_USER_PERMISSION_READER, $with_image = false)
2579
    {
2580
        $table_group_rel_user = $this->usergroup_rel_user_table;
2581
        $tbl_group = $this->table;
2582
        $user_id = (int) $user_id;
2583
2584
        if ($relationType == 0) {
2585
            $relationCondition = '';
2586
        } else {
2587
            if (is_array($relationType)) {
2588
                $relationType = array_map('intval', $relationType);
2589
                $relationType = implode("','", $relationType);
2590
                $relationCondition = " AND ( gu.relation_type IN ('$relationType')) ";
2591
            } else {
2592
                $relationType = (int) $relationType;
2593
                $relationCondition = " AND gu.relation_type = $relationType ";
2594
            }
2595
        }
2596
2597
        $sql = 'SELECT
2598
                    g.picture,
2599
                    g.name,
2600
                    g.description,
2601
                    g.id ,
2602
                    gu.relation_type';
2603
2604
        $urlCondition = '';
2605
        if ($this->getUseMultipleUrl()) {
2606
            $sql .= " FROM $tbl_group g
2607
                    INNER JOIN ".$this->access_url_rel_usergroup." a
2608
                    ON (g.id = a.usergroup_id)
2609
                    INNER JOIN $table_group_rel_user gu
2610
                    ON gu.usergroup_id = g.id";
2611
            $urlId = api_get_current_access_url_id();
2612
            $urlCondition = " AND access_url_id = $urlId ";
2613
        } else {
2614
            $sql .= " FROM $tbl_group g
2615
                    INNER JOIN $table_group_rel_user gu
2616
                    ON gu.usergroup_id = g.id";
2617
        }
2618
2619
        $sql .= " WHERE
2620
				    g.group_type = ".self::SOCIAL_CLASS." AND
2621
                    gu.user_id = $user_id
2622
                    $relationCondition
2623
                    $urlCondition
2624
                ORDER BY created_at DESC ";
2625
        $result = Database::query($sql);
2626
        $array = [];
2627
        if (Database::num_rows($result) > 0) {
2628
            while ($row = Database::fetch_array($result, 'ASSOC')) {
2629
                if ($with_image) {
2630
                    $picture = $this->get_picture_group($row['id'], $row['picture'], 80);
2631
                    $img = '<img src="'.$picture['file'].'" />';
2632
                    $row['picture'] = $img;
2633
                }
2634
                $array[$row['id']] = $row;
2635
            }
2636
        }
2637
2638
        return $array;
2639
    }
2640
2641
    /**
2642
     * Gets the inner join of users and group table.
2643
     *
2644
     * @param int  quantity of records
2645
     * @param bool show groups with image or not
2646
     *
2647
     * @return array with group content
2648
     *
2649
     * @author Julio Montoya
2650
     * */
2651
    public function get_groups_by_popularity($num = 6, $with_image = true)
2652
    {
2653
        $table_group_rel_user = $this->usergroup_rel_user_table;
2654
        $tbl_group = $this->table;
2655
        if (empty($num)) {
2656
            $num = 6;
2657
        } else {
2658
            $num = (int) $num;
2659
        }
2660
        // only show admins and readers
2661
        $whereCondition = " WHERE
2662
                              g.group_type = ".self::SOCIAL_CLASS." AND
2663
                              gu.relation_type IN
2664
                              ('".GROUP_USER_PERMISSION_ADMIN."' , '".GROUP_USER_PERMISSION_READER."', '".GROUP_USER_PERMISSION_HRM."') ";
2665
2666
        $sql = 'SELECT DISTINCT count(user_id) as count, g.picture, g.name, g.description, g.id ';
2667
2668
        $urlCondition = '';
2669
        if ($this->getUseMultipleUrl()) {
2670
            $sql .= " FROM $tbl_group g
2671
                    INNER JOIN ".$this->access_url_rel_usergroup." a
2672
                    ON (g.id = a.usergroup_id)
2673
                    INNER JOIN $table_group_rel_user gu
2674
                    ON gu.usergroup_id = g.id";
2675
            $urlId = api_get_current_access_url_id();
2676
            $urlCondition = " AND access_url_id = $urlId ";
2677
        } else {
2678
            $sql .= " FROM $tbl_group g
2679
                    INNER JOIN $table_group_rel_user gu
2680
                    ON gu.usergroup_id = g.id";
2681
        }
2682
2683
        $sql .= "
2684
				$whereCondition
2685
				$urlCondition
2686
				GROUP BY g.id
2687
				ORDER BY count DESC
2688
				LIMIT $num";
2689
2690
        $result = Database::query($sql);
2691
        $array = [];
2692
        while ($row = Database::fetch_array($result, 'ASSOC')) {
2693
            if ($with_image) {
2694
                $picture = $this->get_picture_group($row['id'], $row['picture'], 80);
2695
                $img = '<img src="'.$picture['file'].'" />';
2696
                $row['picture'] = $img;
2697
            }
2698
            if (empty($row['id'])) {
2699
                continue;
2700
            }
2701
            $array[$row['id']] = $row;
2702
        }
2703
2704
        return $array;
2705
    }
2706
2707
    /**
2708
     * Gets the last groups created.
2709
     *
2710
     * @param int  $num       quantity of records
2711
     * @param bool $withImage show groups with image or not
2712
     *
2713
     * @return array with group content
2714
     *
2715
     * @author Julio Montoya
2716
     * */
2717
    public function get_groups_by_age($num = 6, $withImage = true)
2718
    {
2719
        $table_group_rel_user = $this->usergroup_rel_user_table;
2720
        $tbl_group = $this->table;
2721
2722
        if (empty($num)) {
2723
            $num = 6;
2724
        } else {
2725
            $num = (int) $num;
2726
        }
2727
2728
        $where = " WHERE
2729
                        g.group_type = ".self::SOCIAL_CLASS." AND
2730
                        gu.relation_type IN
2731
                        ('".GROUP_USER_PERMISSION_ADMIN."' ,
2732
                        '".GROUP_USER_PERMISSION_READER."',
2733
                        '".GROUP_USER_PERMISSION_MODERATOR."',
2734
                        '".GROUP_USER_PERMISSION_HRM."')
2735
                    ";
2736
        $sql = 'SELECT DISTINCT
2737
                  count(user_id) as count,
2738
                  g.picture,
2739
                  g.name,
2740
                  g.description,
2741
                  g.id ';
2742
2743
        $urlCondition = '';
2744
        if ($this->getUseMultipleUrl()) {
2745
            $sql .= " FROM $tbl_group g
2746
                    INNER JOIN ".$this->access_url_rel_usergroup." a
2747
                    ON (g.id = a.usergroup_id)
2748
                    INNER JOIN $table_group_rel_user gu
2749
                    ON gu.usergroup_id = g.id";
2750
            $urlId = api_get_current_access_url_id();
2751
            $urlCondition = " AND access_url_id = $urlId ";
2752
        } else {
2753
            $sql .= " FROM $tbl_group g
2754
                    INNER JOIN $table_group_rel_user gu
2755
                    ON gu.usergroup_id = g.id";
2756
        }
2757
        $sql .= "
2758
                $where
2759
                $urlCondition
2760
                GROUP BY g.id
2761
                ORDER BY created_at DESC
2762
                LIMIT $num ";
2763
2764
        $result = Database::query($sql);
2765
        $array = [];
2766
        while ($row = Database::fetch_array($result, 'ASSOC')) {
2767
            if ($withImage) {
2768
                $picture = $this->get_picture_group($row['id'], $row['picture'], 80);
2769
                $img = '<img src="'.$picture['file'].'" />';
2770
                $row['picture'] = $img;
2771
            }
2772
            if (empty($row['id'])) {
2773
                continue;
2774
            }
2775
            $array[$row['id']] = $row;
2776
        }
2777
2778
        return $array;
2779
    }
2780
2781
    /**
2782
     * Gets the group's members.
2783
     *
2784
     * @param int group id
2785
     * @param bool show image or not of the group
2786
     * @param array list of relation type use constants
2787
     * @param int from value
2788
     * @param int limit
2789
     * @param array image configuration, i.e array('height'=>'20px', 'size'=> '20px')
2790
     *
2791
     * @return array list of users in a group
2792
     */
2793
    public function get_users_by_group(
2794
        $group_id,
2795
        $withImage = false,
2796
        $relation_type = [],
2797
        $from = null,
2798
        $limit = null
2799
    ) {
2800
        $table_group_rel_user = $this->usergroup_rel_user_table;
2801
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
2802
        $group_id = (int) $group_id;
2803
2804
        if (empty($group_id)) {
2805
            return [];
2806
        }
2807
2808
        $limit_text = '';
2809
        if (isset($from) && isset($limit)) {
2810
            $from = (int) $from;
2811
            $limit = (int) $limit;
2812
            $limit_text = "LIMIT $from, $limit";
2813
        }
2814
2815
        if (count($relation_type) == 0) {
2816
            $where_relation_condition = '';
2817
        } else {
2818
            $new_relation_type = [];
2819
            foreach ($relation_type as $rel) {
2820
                $rel = (int) $rel;
2821
                $new_relation_type[] = "'$rel'";
2822
            }
2823
            $relation_type = implode(',', $new_relation_type);
2824
            if (!empty($relation_type)) {
2825
                $where_relation_condition = "AND gu.relation_type IN ($relation_type) ";
2826
            }
2827
        }
2828
2829
        $sql = "SELECT
2830
                    picture_uri as image,
2831
                    u.id,
2832
                    CONCAT (u.firstname,' ', u.lastname) as fullname,
2833
                    relation_type
2834
    		    FROM $tbl_user u
2835
    		    INNER JOIN $table_group_rel_user gu
2836
    			ON (gu.user_id = u.id)
2837
    			WHERE
2838
    			    gu.usergroup_id= $group_id
2839
    			    $where_relation_condition
2840
    			ORDER BY relation_type, firstname
2841
    			$limit_text";
2842
2843
        $result = Database::query($sql);
2844
        $array = [];
2845
        while ($row = Database::fetch_array($result, 'ASSOC')) {
2846
            if ($withImage) {
2847
                $userInfo = api_get_user_info($row['id']);
2848
                $userPicture = UserManager::getUserPicture($row['id']);
2849
                $row['image'] = '<img src="'.$userPicture.'"  />';
2850
                $row['user_info'] = $userInfo;
2851
            }
2852
2853
            $row['user_id'] = $row['id'];
2854
            $array[$row['id']] = $row;
2855
        }
2856
2857
        return $array;
2858
    }
2859
2860
    /**
2861
     * Gets all the members of a group no matter the relationship for
2862
     * more specifications use get_users_by_group.
2863
     *
2864
     * @param int group id
2865
     *
2866
     * @return array
2867
     */
2868
    public function get_all_users_by_group($group_id)
2869
    {
2870
        $table_group_rel_user = $this->usergroup_rel_user_table;
2871
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
2872
        $group_id = (int) $group_id;
2873
2874
        if (empty($group_id)) {
2875
            return [];
2876
        }
2877
2878
        $sql = "SELECT u.id, u.firstname, u.lastname, gu.relation_type
2879
                FROM $tbl_user u
2880
			    INNER JOIN $table_group_rel_user gu
2881
			    ON (gu.user_id = u.id)
2882
			    WHERE gu.usergroup_id= $group_id
2883
			    ORDER BY relation_type, firstname";
2884
2885
        $result = Database::query($sql);
2886
        $array = [];
2887
        while ($row = Database::fetch_array($result, 'ASSOC')) {
2888
            $array[$row['id']] = $row;
2889
        }
2890
2891
        return $array;
2892
    }
2893
2894
    /**
2895
     * Shows the left column of the group page.
2896
     *
2897
     * @param int    $group_id
2898
     * @param int    $user_id
2899
     * @param string $show
2900
     *
2901
     * @return string
2902
     */
2903
    public function show_group_column_information($group_id, $user_id, $show = '')
2904
    {
2905
        $html = '';
2906
        $group_info = $this->get($group_id);
2907
2908
        //my relation with the group is set here
2909
        $my_group_role = $this->get_user_group_role($user_id, $group_id);
2910
2911
        // Loading group permission
2912
        $links = '';
2913
        switch ($my_group_role) {
2914
            case GROUP_USER_PERMISSION_READER:
2915
                // I'm just a reader
2916
                $relation_group_title = get_lang('IAmAReader');
2917
                $links .= '<li class="'.($show == 'invite_friends' ? 'active' : '').'"><a href="group_invitation.php?id='.$group_id.'">'.
2918
                            Display::return_icon('invitation_friend.png', get_lang('InviteFriends')).get_lang('InviteFriends').'</a></li>';
2919
                if (self::canLeave($group_info)) {
2920
                    $links .= '<li><a href="group_view.php?id='.$group_id.'&action=leave&u='.api_get_user_id().'">'.
2921
                        Display::return_icon('group_leave.png', get_lang('LeaveGroup')).get_lang('LeaveGroup').'</a></li>';
2922
                }
2923
                break;
2924
            case GROUP_USER_PERMISSION_ADMIN:
2925
                $relation_group_title = get_lang('IAmAnAdmin');
2926
                $links .= '<li class="'.($show == 'group_edit' ? 'active' : '').'"><a href="group_edit.php?id='.$group_id.'">'.
2927
                            Display::return_icon('group_edit.png', get_lang('EditGroup')).get_lang('EditGroup').'</a></li>';
2928
                $links .= '<li class="'.($show == 'member_list' ? 'active' : '').'"><a href="group_waiting_list.php?id='.$group_id.'">'.
2929
                            Display::return_icon('waiting_list.png', get_lang('WaitingList')).get_lang('WaitingList').'</a></li>';
2930
                $links .= '<li class="'.($show == 'invite_friends' ? 'active' : '').'"><a href="group_invitation.php?id='.$group_id.'">'.
2931
                            Display::return_icon('invitation_friend.png', get_lang('InviteFriends')).get_lang('InviteFriends').'</a></li>';
2932
                if (self::canLeave($group_info)) {
2933
                    $links .= '<li><a href="group_view.php?id='.$group_id.'&action=leave&u='.api_get_user_id().'">'.
2934
                        Display::return_icon('group_leave.png', get_lang('LeaveGroup')).get_lang('LeaveGroup').'</a></li>';
2935
                }
2936
                break;
2937
            case GROUP_USER_PERMISSION_PENDING_INVITATION:
2938
//				$links .=  '<li><a href="groups.php?id='.$group_id.'&action=join&u='.api_get_user_id().'">'.Display::return_icon('addd.gif', get_lang('YouHaveBeenInvitedJoinNow'), array('hspace'=>'6')).'<span class="social-menu-text4" >'.get_lang('YouHaveBeenInvitedJoinNow').'</span></a></li>';
2939
                break;
2940
            case GROUP_USER_PERMISSION_PENDING_INVITATION_SENT_BY_USER:
2941
                $relation_group_title = get_lang('WaitingForAdminResponse');
2942
                break;
2943
            case GROUP_USER_PERMISSION_MODERATOR:
2944
                $relation_group_title = get_lang('IAmAModerator');
2945
                //$links .=  '<li><a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?view_panel=1&height=400&width=610&&user_friend='.api_get_user_id().'&group_id='.$group_id.'&action=add_message_group" class="thickbox" title="'.get_lang('ComposeMessage').'">'.Display::return_icon('compose_message.png', get_lang('NewTopic'), array('hspace'=>'6')).'<span class="social-menu-text4" >'.get_lang('NewTopic').'</span></a></li>';
2946
                //$links .=  '<li><a href="groups.php?id='.$group_id.'">'.				Display::return_icon('message_list.png', get_lang('MessageList'), array('hspace'=>'6')).'<span class="'.($show=='messages_list'?'social-menu-text-active':'social-menu-text4').'" >'.get_lang('MessageList').'</span></a></li>';
2947
                //$links .=  '<li><a href="group_members.php?id='.$group_id.'">'.		Display::return_icon('member_list.png', get_lang('MemberList'), array('hspace'=>'6')).'<span class="'.($show=='member_list'?'social-menu-text-active':'social-menu-text4').'" >'.get_lang('MemberList').'</span></a></li>';
2948
                if ($group_info['visibility'] == GROUP_PERMISSION_CLOSED) {
2949
                    $links .= '<li><a href="group_waiting_list.php?id='.$group_id.'">'.
2950
                                Display::return_icon('waiting_list.png', get_lang('WaitingList')).get_lang('WaitingList').'</a></li>';
2951
                }
2952
                $links .= '<li><a href="group_invitation.php?id='.$group_id.'">'.
2953
                            Display::return_icon('invitation_friend.png', get_lang('InviteFriends')).get_lang('InviteFriends').'</a></li>';
2954
                if (self::canLeave($group_info)) {
2955
                    $links .= '<li><a href="group_view.php?id='.$group_id.'&action=leave&u='.api_get_user_id().'">'.
2956
                        Display::return_icon('group_leave.png', get_lang('LeaveGroup')).get_lang('LeaveGroup').'</a></li>';
2957
                }
2958
                break;
2959
            case GROUP_USER_PERMISSION_HRM:
2960
                $relation_group_title = get_lang('IAmAHRM');
2961
                $links .= '<li><a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?view_panel=1&height=400&width=610&&user_friend='.api_get_user_id().'&group_id='.$group_id.'&action=add_message_group" class="ajax" title="'.get_lang('ComposeMessage').'" data-size="lg" data-title="'.get_lang('ComposeMessage').'">'.
2962
                            Display::return_icon('new-message.png', get_lang('NewTopic')).get_lang('NewTopic').'</a></li>';
2963
                $links .= '<li><a href="group_view.php?id='.$group_id.'">'.
2964
                            Display::return_icon('message_list.png', get_lang('MessageList')).get_lang('MessageList').'</a></li>';
2965
                $links .= '<li><a href="group_invitation.php?id='.$group_id.'">'.
2966
                            Display::return_icon('invitation_friend.png', get_lang('InviteFriends')).get_lang('InviteFriends').'</a></li>';
2967
                $links .= '<li><a href="group_members.php?id='.$group_id.'">'.
2968
                            Display::return_icon('member_list.png', get_lang('MemberList')).get_lang('MemberList').'</a></li>';
2969
                $links .= '<li><a href="group_view.php?id='.$group_id.'&action=leave&u='.api_get_user_id().'">'.
2970
                            Display::return_icon('delete_data.gif', get_lang('LeaveGroup')).get_lang('LeaveGroup').'</a></li>';
2971
                break;
2972
            default:
2973
                //$links .=  '<li><a href="groups.php?id='.$group_id.'&action=join&u='.api_get_user_id().'">'.Display::return_icon('addd.gif', get_lang('JoinGroup'), array('hspace'=>'6')).'<span class="social-menu-text4" >'.get_lang('JoinGroup').'</a></span></li>';
2974
                break;
2975
        }
2976
        if (!empty($links)) {
2977
            $list = '<ul class="nav nav-pills">';
2978
            $list .= $links;
2979
            $list .= '</ul>';
2980
            $html .= Display::panelCollapse(
2981
                get_lang('SocialGroups'),
2982
                $list,
2983
                'sm-groups',
2984
                [],
2985
                'groups-acordeon',
2986
                'groups-collapse'
2987
            );
2988
        }
2989
2990
        return $html;
2991
    }
2992
2993
    /**
2994
     * @param int $group_id
2995
     * @param int $topic_id
2996
     */
2997
    public function delete_topic($group_id, $topic_id)
2998
    {
2999
        $table_message = Database::get_main_table(TABLE_MESSAGE);
3000
        $topic_id = (int) $topic_id;
3001
        $group_id = (int) $group_id;
3002
3003
        $sql = "UPDATE $table_message SET
3004
                    msg_status = 3
3005
                WHERE
3006
                    group_id = $group_id AND
3007
                    (id = '$topic_id' OR parent_id = $topic_id)
3008
                ";
3009
        Database::query($sql);
3010
    }
3011
3012
    /**
3013
     * @param string $user_id
3014
     * @param string $relation_type
3015
     * @param bool   $with_image
3016
     *
3017
     * @deprecated
3018
     *
3019
     * @return int
3020
     */
3021
    public function get_groups_by_user_count(
3022
        $user_id = '',
3023
        $relation_type = GROUP_USER_PERMISSION_READER,
3024
        $with_image = false
3025
    ) {
3026
        $table_group_rel_user = $this->usergroup_rel_user_table;
3027
        $tbl_group = $this->table;
3028
        $user_id = intval($user_id);
3029
3030
        if ($relation_type == 0) {
3031
            $where_relation_condition = '';
3032
        } else {
3033
            $relation_type = intval($relation_type);
3034
            $where_relation_condition = "AND gu.relation_type = $relation_type ";
3035
        }
3036
3037
        $sql = "SELECT count(g.id) as count
3038
				FROM $tbl_group g
3039
				INNER JOIN $table_group_rel_user gu
3040
				ON gu.usergroup_id = g.id
3041
				WHERE gu.user_id = $user_id $where_relation_condition ";
3042
3043
        $result = Database::query($sql);
3044
        if (Database::num_rows($result) > 0) {
3045
            $row = Database::fetch_array($result, 'ASSOC');
3046
3047
            return $row['count'];
3048
        }
3049
3050
        return 0;
3051
    }
3052
3053
    /**
3054
     * @param string $tag
3055
     * @param int    $from
3056
     * @param int    $number_of_items
3057
     *
3058
     * @return array
3059
     */
3060
    public function get_all_group_tags($tag = '', $from = 0, $number_of_items = 10, $getCount = false)
3061
    {
3062
        $group_table = $this->table;
3063
        $tag = Database::escape_string($tag);
3064
        $from = (int) $from;
3065
        $number_of_items = (int) $number_of_items;
3066
        $return = [];
3067
3068
        $keyword = $tag;
3069
        $sql = 'SELECT  g.id, g.name, g.description, g.url, g.picture ';
3070
        $urlCondition = '';
3071
        if ($this->getUseMultipleUrl()) {
3072
            $urlId = api_get_current_access_url_id();
3073
            $sql .= " FROM $this->table g
3074
                    INNER JOIN $this->access_url_rel_usergroup a
3075
                    ON (g.id = a.usergroup_id)";
3076
            $urlCondition = " AND access_url_id = $urlId ";
3077
        } else {
3078
            $sql .= " FROM $group_table g";
3079
        }
3080
        if (isset($keyword)) {
3081
            $sql .= " WHERE (
3082
                        g.name LIKE '%".$keyword."%' OR
3083
                        g.description LIKE '%".$keyword."%' OR
3084
                        g.url LIKE '%".$keyword."%'
3085
                     ) $urlCondition
3086
                     ";
3087
        } else {
3088
            $sql .= " WHERE 1 = 1 $urlCondition ";
3089
        }
3090
3091
        $direction = 'ASC';
3092
        if (!in_array($direction, ['ASC', 'DESC'])) {
3093
            $direction = 'ASC';
3094
        }
3095
3096
        $from = (int) $from;
3097
        $number_of_items = (int) $number_of_items;
3098
        $sql .= " LIMIT $from, $number_of_items";
3099
3100
        $res = Database::query($sql);
3101
        if (Database::num_rows($res) > 0) {
3102
            while ($row = Database::fetch_array($res, 'ASSOC')) {
3103
                if (!in_array($row['id'], $return)) {
3104
                    $return[$row['id']] = $row;
3105
                }
3106
            }
3107
        }
3108
3109
        return $return;
3110
    }
3111
3112
    /**
3113
     * @param int $group_id
3114
     *
3115
     * @return array
3116
     */
3117
    public static function get_parent_groups($group_id)
3118
    {
3119
        $t_rel_group = Database::get_main_table(TABLE_USERGROUP_REL_USERGROUP);
3120
        $group_id = (int) $group_id;
3121
3122
        $max_level = 10;
3123
        $select_part = 'SELECT ';
3124
        $cond_part = '';
3125
        for ($i = 1; $i <= $max_level; $i++) {
3126
            $rg_number = $i - 1;
3127
            if ($i == $max_level) {
3128
                $select_part .= "rg$rg_number.group_id as id_$rg_number ";
3129
            } else {
3130
                $select_part .= "rg$rg_number.group_id as id_$rg_number, ";
3131
            }
3132
            if ($i == 1) {
3133
                $cond_part .= "FROM $t_rel_group rg0
3134
                               LEFT JOIN $t_rel_group rg$i
3135
                               ON rg$rg_number.group_id = rg$i.subgroup_id ";
3136
            } else {
3137
                $cond_part .= " LEFT JOIN $t_rel_group rg$i
3138
                                ON rg$rg_number.group_id = rg$i.subgroup_id ";
3139
            }
3140
        }
3141
        $sql = $select_part.' '.$cond_part."WHERE rg0.subgroup_id='$group_id'";
3142
        $res = Database::query($sql);
3143
        $temp_arr = Database::fetch_array($res, 'NUM');
3144
        $toReturn = [];
3145
        if (is_array($temp_arr)) {
3146
            foreach ($temp_arr as $elt) {
3147
                if (isset($elt)) {
3148
                    $toReturn[] = $elt;
3149
                }
3150
            }
3151
        }
3152
3153
        return $toReturn;
3154
    }
3155
3156
    /**
3157
     * Get the group member list by a user and his group role.
3158
     *
3159
     * @param int  $userId                The user ID
3160
     * @param int  $relationType          Optional. The relation type. GROUP_USER_PERMISSION_ADMIN by default
3161
     * @param bool $includeSubgroupsUsers Optional. Whether include the users from subgroups
3162
     *
3163
     * @return array
3164
     */
3165
    public function getGroupUsersByUser(
3166
        $userId,
3167
        $relationType = GROUP_USER_PERMISSION_ADMIN,
3168
        $includeSubgroupsUsers = true
3169
    ) {
3170
        $userId = (int) $userId;
3171
        $groups = $this->get_groups_by_user($userId, $relationType);
3172
        $groupsId = array_keys($groups);
3173
        $subgroupsId = [];
3174
        $userIdList = [];
3175
3176
        if ($includeSubgroupsUsers) {
3177
            foreach ($groupsId as $groupId) {
3178
                $subgroupsId = array_merge($subgroupsId, self::getGroupsByDepthLevel($groupId));
3179
            }
3180
3181
            $groupsId = array_merge($groupsId, $subgroupsId);
3182
        }
3183
3184
        $groupsId = array_unique($groupsId);
3185
3186
        if (empty($groupsId)) {
3187
            return [];
3188
        }
3189
3190
        foreach ($groupsId as $groupId) {
3191
            $groupUsers = $this->get_users_by_group($groupId);
3192
3193
            if (empty($groupUsers)) {
3194
                continue;
3195
            }
3196
3197
            foreach ($groupUsers as $member) {
3198
                if ($member['user_id'] == $userId) {
3199
                    continue;
3200
                }
3201
3202
                $userIdList[] = (int) $member['user_id'];
3203
            }
3204
        }
3205
3206
        return array_unique($userIdList);
3207
    }
3208
3209
    /**
3210
     * Get the subgroups ID from a group.
3211
     * The default $levels value is 10 considering it as a extensive level of depth.
3212
     *
3213
     * @param int $groupId The parent group ID
3214
     * @param int $levels  The depth levels
3215
     *
3216
     * @return array The list of ID
3217
     */
3218
    public static function getGroupsByDepthLevel($groupId, $levels = 10)
3219
    {
3220
        $groups = [];
3221
        $groupId = (int) $groupId;
3222
3223
        $groupTable = Database::get_main_table(TABLE_USERGROUP);
3224
        $groupRelGroupTable = Database::get_main_table(TABLE_USERGROUP_REL_USERGROUP);
3225
3226
        $select = 'SELECT ';
3227
        $from = "FROM $groupTable g1 ";
3228
3229
        for ($i = 1; $i <= $levels; $i++) {
3230
            $tableIndexNumber = $i;
3231
            $tableIndexJoinNumber = $i - 1;
3232
            $select .= "g$i.id as id_$i ";
3233
            $select .= $i != $levels ? ', ' : null;
3234
3235
            if ($i == 1) {
3236
                $from .= " INNER JOIN $groupRelGroupTable gg0
3237
                           ON g1.id = gg0.subgroup_id and gg0.group_id = $groupId ";
3238
            } else {
3239
                $from .= "LEFT JOIN $groupRelGroupTable gg$tableIndexJoinNumber ";
3240
                $from .= " ON g$tableIndexJoinNumber.id = gg$tableIndexJoinNumber.group_id ";
3241
                $from .= "LEFT JOIN $groupTable g$tableIndexNumber ";
3242
                $from .= " ON gg$tableIndexJoinNumber.subgroup_id = g$tableIndexNumber.id ";
3243
            }
3244
        }
3245
3246
        $result = Database::query("$select $from");
3247
3248
        while ($item = Database::fetch_assoc($result)) {
3249
            foreach ($item as $myGroupId) {
3250
                if (!empty($myGroupId)) {
3251
                    $groups[] = $myGroupId;
3252
                }
3253
            }
3254
        }
3255
3256
        return array_map('intval', $groups);
3257
    }
3258
3259
    /**
3260
     * Set a parent group.
3261
     *
3262
     * @param int $group_id
3263
     * @param int $parent_group_id if 0, we delete the parent_group association
3264
     * @param int $relation_type
3265
     *
3266
     * @return \Doctrine\DBAL\Statement
3267
     */
3268
    public function setParentGroup($group_id, $parent_group_id, $relation_type = 1)
3269
    {
3270
        $table = Database::get_main_table(TABLE_USERGROUP_REL_USERGROUP);
3271
        $group_id = (int) $group_id;
3272
        $parent_group_id = (int) $parent_group_id;
3273
        if ($parent_group_id == 0) {
3274
            $sql = "DELETE FROM $table WHERE subgroup_id = $group_id";
3275
        } else {
3276
            $sql = "SELECT group_id FROM $table WHERE subgroup_id = $group_id";
3277
            $res = Database::query($sql);
3278
            if (Database::num_rows($res) == 0) {
3279
                $sql = "INSERT INTO $table SET
3280
                        group_id = $parent_group_id,
3281
                        subgroup_id = $group_id,
3282
                        relation_type = $relation_type";
3283
            } else {
3284
                $sql = "UPDATE $table SET
3285
                        group_id = $parent_group_id,
3286
                        relation_type = $relation_type
3287
                        WHERE subgroup_id = $group_id";
3288
            }
3289
        }
3290
        $res = Database::query($sql);
3291
3292
        return $res;
3293
    }
3294
3295
    /**
3296
     * Filter the groups/classes info to get a name list only.
3297
     *
3298
     * @param int $userId       The user ID
3299
     * @param int $filterByType Optional. The type of group
3300
     *
3301
     * @return array
3302
     */
3303
    public function getNameListByUser($userId, $filterByType = null)
3304
    {
3305
        $userClasses = $this->getUserGroupListByUser($userId, $filterByType);
3306
3307
        return array_column($userClasses, 'name');
3308
    }
3309
3310
    /**
3311
     * Get the HTML necessary for display the groups/classes name list.
3312
     *
3313
     * @param int $userId       The user ID
3314
     * @param int $filterByType Optional. The type of group
3315
     *
3316
     * @return string
3317
     */
3318
    public function getLabelsFromNameList($userId, $filterByType = null)
3319
    {
3320
        $groupsNameListParsed = $this->getNameListByUser($userId, $filterByType);
3321
3322
        if (empty($groupsNameListParsed)) {
3323
            return '';
3324
        }
3325
3326
        $nameList = '<ul class="list-unstyled">';
3327
        foreach ($groupsNameListParsed as $name) {
3328
            $nameList .= '<li>'.Display::span($name, ['class' => 'label label-info']).'</li>';
3329
        }
3330
3331
        $nameList .= '</ul>';
3332
3333
        return $nameList;
3334
    }
3335
3336
    /**
3337
     * @param array $groupInfo
3338
     *
3339
     * @return bool
3340
     */
3341
    public static function canLeave($groupInfo)
3342
    {
3343
        return $groupInfo['allow_members_leave_group'] == 1 ? true : false;
3344
    }
3345
3346
    /**
3347
     * Check permissions and blocks the page.
3348
     *
3349
     * @param array $userGroupInfo
3350
     * @param bool  $checkAuthor
3351
     * @param bool  $checkCourseIsAllow
3352
     */
3353
    public function protectScript($userGroupInfo = [], $checkAuthor = true, $checkCourseIsAllow = false)
3354
    {
3355
        api_block_anonymous_users();
3356
3357
        if (api_is_platform_admin()) {
3358
            return true;
3359
        }
3360
3361
        if ($checkCourseIsAllow) {
3362
            if (api_is_allowed_to_edit()) {
3363
                return true;
3364
            }
3365
        }
3366
3367
        if ($this->allowTeachers() && api_is_teacher()) {
3368
            if ($checkAuthor && !empty($userGroupInfo)) {
3369
                if (isset($userGroupInfo['author_id']) && $userGroupInfo['author_id'] != api_get_user_id()) {
3370
                    api_not_allowed(true);
3371
                }
3372
            }
3373
3374
            return true;
3375
        } else {
3376
            api_protect_admin_script(true);
3377
            api_protect_limit_for_session_admin();
3378
        }
3379
    }
3380
3381
    public function getGroupsByLp($lpId, $courseId, $sessionId)
3382
    {
3383
        $lpId = (int) $lpId;
3384
        $courseId = (int) $courseId;
3385
        $sessionId = (int) $sessionId;
3386
        $sessionCondition = api_get_session_condition($sessionId, true);
3387
        $table = Database::get_course_table(TABLE_LP_REL_USERGROUP);
3388
        $sql = "SELECT usergroup_id FROM $table
3389
                WHERE
3390
                    c_id = $courseId AND
3391
                    lp_id = $lpId
3392
                    $sessionCondition
3393
                    ";
3394
        $result = Database::query($sql);
3395
3396
        return Database::store_result($result, 'ASSOC');
3397
    }
3398
3399
    public function getGroupsByLpCategory($categoryId, $courseId, $sessionId)
3400
    {
3401
        $categoryId = (int) $categoryId;
3402
        $courseId = (int) $courseId;
3403
        $sessionId = (int) $sessionId;
3404
        $sessionCondition = api_get_session_condition($sessionId, true);
3405
3406
        $table = Database::get_course_table(TABLE_LP_CATEGORY_REL_USERGROUP);
3407
        $sql = "SELECT usergroup_id FROM $table
3408
                WHERE
3409
                    c_id = $courseId AND
3410
                    lp_category_id = $categoryId
3411
                    $sessionCondition
3412
                ";
3413
        $result = Database::query($sql);
3414
3415
        return Database::store_result($result, 'ASSOC');
3416
    }
3417
3418
    /**
3419
     * Check the given ID matches an existing group.
3420
     *
3421
     * @return bool
3422
     */
3423
    public function groupExists(int $groupId)
3424
    {
3425
        $sql = "SELECT id FROM ".$this->table." WHERE id = ".$groupId;
3426
        $result = Database::query($sql);
3427
        if (Database::num_rows($result) === 1) {
3428
            return true;
3429
        }
3430
3431
        return false;
3432
    }
3433
3434
    /**
3435
     * Check the given ID matches an existing user.
3436
     *
3437
     * @return bool
3438
     */
3439
    public function userExists(int $userId)
3440
    {
3441
        $sql = "SELECT id FROM ".$this->table_user." WHERE id = ".$userId;
3442
        $result = Database::query($sql);
3443
        if (Database::num_rows($result) === 1) {
3444
            return true;
3445
        }
3446
3447
        return false;
3448
    }
3449
}
3450