Passed
Push — master ( 673bfc...65df8d )
by Julito
09:32
created

UserGroupModel::getUserGroupNotInCourse()   F

Complexity

Conditions 23
Paths 7426

Size

Total Lines 132
Code Lines 84

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 23
eloc 84
c 0
b 0
f 0
nc 7426
nop 4
dl 0
loc 132
rs 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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