Passed
Pull Request — master (#6360)
by
unknown
11:33
created

UserGroupModel::getGroupType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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