Passed
Push — master ( 447a4c...2f567c )
by Julito
09:40
created

UserGroup::get_groups_by_popularity()   B

Complexity

Conditions 6
Paths 20

Size

Total Lines 54
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 35
c 1
b 0
f 0
nc 20
nop 2
dl 0
loc 54
rs 8.7377

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

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