Passed
Pull Request — master (#6880)
by Yannick
11:17
created

UserGroupModel::canLeave()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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