UserGroupModel::get_usergroup_by_course()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 29
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

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