Completed
Push — master ( 8b2aa0...562606 )
by Julito
09:06
created

UserGroup   F

Complexity

Total Complexity 373

Size/Duplication

Total Lines 2859
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 1392
dl 0
loc 2859
rs 0.8
c 3
b 0
f 0
wmc 373

72 Methods

Rating   Name   Duplication   Size   Complexity  
A getUseMultipleUrl() 0 3 1
A getTotalCount() 0 21 2
C getUserGroupUsers() 0 86 12
A __construct() 0 14 2
A returnGrid() 0 30 2
B get_count() 0 41 6
A getIdByName() 0 10 1
B get_users_by_usergroup() 0 38 7
C subscribe_courses_to_usergroup() 0 46 13
A get_usergroup_by_user() 0 28 4
A display_teacher_view() 0 3 1
A allowTeachers() 0 3 1
A getUsersByUsergroupAndRelation() 0 23 4
A get_sessions_by_usergroup() 0 16 3
A getUserGroupNotInList() 0 25 3
B get_courses_by_usergroup() 0 44 7
A getUserGroupListByUser() 0 37 5
C subscribe_sessions_to_usergroup() 0 50 15
A usergroup_exists() 0 16 2
B getUsergroupsPagination() 0 73 10
B getDataToExport() 0 37 8
A unsubscribe_courses_from_usergroup() 0 24 6
B save() 0 40 10
D subscribe_users_to_usergroup() 0 96 21
A usergroup_was_added_in_course() 0 13 2
A filterByFirstLetter() 0 31 3
A is_group_member() 0 19 4
A getGroupType() 0 3 1
A getNameListByUser() 0 5 1
A canLeave() 0 3 2
A setGroupType() 0 3 1
A displayToolBarUserGroupUsers() 0 18 2
B get_groups_by_popularity() 0 54 6
B getGroupsByDepthLevel() 0 39 7
A update_user_role() 0 11 1
B getUserGroupNotInCourse() 0 63 8
B get_picture_group() 0 53 10
A get_groups_by_user_count() 0 30 3
A getUserListByUserGroup() 0 11 1
A getGroupStatusList() 0 8 1
B get_groups_by_user() 0 61 7
C update() 0 28 10
A delete() 0 20 2
B getGroupUsersByUser() 0 42 8
C show_group_column_information() 0 88 16
A delete_user_rel_group() 0 17 3
A delete_topic() 0 13 1
A subscribeToUrl() 0 7 1
B add_users_to_groups() 0 32 7
A delete_group_picture() 0 3 1
A add_user_to_group() 0 20 5
A manageFileUpload() 0 12 2
B get_groups_by_age() 0 62 6
A is_group_admin() 0 10 3
A searchUserGroupAjax() 0 32 4
A get_user_group_role() 0 21 4
A getAllowedPictureExtensions() 0 3 1
B get_parent_groups() 0 37 7
C get_group_picture_path_by_id() 0 45 13
A getUserRoleToString() 0 24 6
A getLabelsFromNameList() 0 16 3
A get_usergroup_by_course() 0 29 4
B getUserGroupInCourse() 0 52 7
A unsubscribeToUrl() 0 6 1
B get_users_by_group() 0 60 9
B setForm() 0 72 7
A isGroupModerator() 0 10 3
B update_group_picture() 0 64 10
B protectScript() 0 25 10
A get_all_users_by_group() 0 24 3
A setParentGroup() 0 25 3
B get_all_group_tags() 0 50 7

How to fix   Complexity   

Complex Class

Complex classes like UserGroup often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use UserGroup, and based on these observations, apply Extract Interface, too.

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