UserGroupModel   F
last analyzed

Complexity

Total Complexity 396

Size/Duplication

Total Lines 3084
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 1515
c 2
b 0
f 0
dl 0
loc 3084
rs 0.8
wmc 396

75 Methods

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

How to fix   Complexity   

Complex Class

Complex classes like UserGroupModel 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 UserGroupModel, and based on these observations, apply Extract Interface, too.

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