Passed
Push — master ( 21b2ac...c8a0b7 )
by
unknown
16:13 queued 08:02
created

UserGroupModel::getRoleName()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 15
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

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