Passed
Push — 1.11.x ( 173904...03717c )
by Julito
11:33
created

UserGroup::getGroupsByLpCategory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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