Passed
Push — master ( ad5dd8...3078de )
by Julito
08:55
created

UserGroup::update_group_picture()   B

Complexity

Conditions 10
Paths 47

Size

Total Lines 64
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 37
nc 47
nop 4
dl 0
loc 64
rs 7.6666
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A UserGroup::subscribeToUrl() 0 7 1
A UserGroup::unsubscribeToUrl() 0 6 1

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