Passed
Push — 1.11.x ( 0d535d...f30747 )
by
unknown
11:33
created

UserGroup::getUserListByUserGroup()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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