Passed
Push — 1.11.x ( 3851b5...3f1029 )
by Julito
10:38 queued 33s
created

UserGroup::get_courses_by_usergroup()   B

Complexity

Conditions 7
Paths 16

Size

Total Lines 44
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

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