Passed
Push — master ( 05e539...3ba91c )
by Julito
08:20
created

UserGroup::getUserGroupInCourse()   F

Complexity

Conditions 22
Paths 2304

Size

Total Lines 122
Code Lines 81

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 22
eloc 81
nc 2304
nop 4
dl 0
loc 122
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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