Passed
Pull Request — master (#6880)
by
unknown
10:05
created

unsubscribe_only_courses_from_usergroup()   B

Complexity

Conditions 7
Paths 11

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

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