1<?php
2/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4/**
5* Base class for course and group participants
6* @author Stefan Meyer <smeyer.ilias@gmx.de>
7* @version $Id$
8*
9* @ingroup ServicesMembership
10*/
11
12define("IL_CRS_ADMIN", 1);
13define("IL_CRS_TUTOR", 3);
14define("IL_CRS_MEMBER", 2);
15
16define('IL_GRP_ADMIN', 4);
17define('IL_GRP_MEMBER', 5);
18
19define('IL_SESS_MEMBER', 6);
20
21define('IL_LSO_ADMIN', 7);
22define('IL_LSO_MEMBER', 8);
23
24define("IL_ROLE_POSITION_ADMIN", 1);
25define("IL_ROLE_POSITION_TUTOR", 2);
26define("IL_ROLE_POSITION_MEMBER", 3);
27
28
29abstract class ilParticipants
30{
31    protected $component = '';
32
33    protected $obj_id = 0;
34    protected $type = '';
35    protected $ref_id = 0;
36
37    protected $roles = array();
38    protected $role_data = array();
39    protected $roles_sorted = [];
40    protected $role_assignments = [];
41
42    protected $participants = array();
43    protected $participants_status = array();
44    protected $members = array();
45    protected $tutors = array();
46    protected $admins = array();
47
48    protected $subscribers = array();
49
50    /**
51     * @var ilDBInterface
52     */
53    protected $ilDB;
54
55    /**
56     * @var ilLanguage
57     */
58    protected $lng;
59
60    /**
61     *
62     * @var \ilLogger
63     */
64    protected $logger = null;
65
66
67    /**
68     * Singleton Constructor
69     *
70     * @access public
71     * @param string component definition e.g Modules/Course
72     * @param int obj_id of container
73     *
74     */
75    public function __construct($a_component_name, $a_ref_id)
76    {
77        $this->ilDB = $GLOBALS['DIC']->database();
78        $this->lng = $GLOBALS['DIC']->language();
79        $this->logger = $GLOBALS['DIC']->logger()->mem();
80
81        $this->component = $a_component_name;
82
83        $this->ref_id = $a_ref_id;
84        $this->obj_id = ilObject::_lookupObjId($a_ref_id);
85        $this->type = ilObject::_lookupType($this->obj_id);
86
87        $this->readParticipants();
88        $this->readParticipantsStatus();
89    }
90
91    /**
92     * Get instance by ref_id
93     * @param int $a_ref_id
94     * @return ilParticipants
95     */
96    public static function getInstance($a_ref_id)
97    {
98        $obj_id = ilObject::_lookupObjId($a_ref_id);
99        $type = ilObject::_lookupType($obj_id);
100
101        switch ($type) {
102            case 'crs':
103            case 'grp':
104            case 'lso':
105                return self::getInstanceByObjId($obj_id);
106            case 'sess':
107                include_once './Modules/Session/classes/class.ilSessionParticipants.php';
108                return ilSessionParticipants::getInstance($a_ref_id);
109            default:
110                $GLOBALS['DIC']->logger()->mem()->logStack();
111                $GLOBALS['DIC']->logger()->mem()->warning('Invalid ref_id -> obj_id given: ' . $a_ref_id . ' -> ' . $obj_id);
112                throw new \InvalidArgumentException('Invalid obj_id given.');
113        }
114    }
115
116    /**
117     * Get instance by obj type
118     *
119     * @param int $a_obj_id
120     * @return ilParticipants
121     * @throws InvalidArgumentException
122     * @deprecated since version 5.4 use getInstance() (ref_id based)
123     */
124    public static function getInstanceByObjId($a_obj_id)
125    {
126        $type = ilObject::_lookupType($a_obj_id);
127        switch ($type) {
128            case 'crs':
129                include_once './Modules/Course/classes/class.ilCourseParticipants.php';
130                return ilCourseParticipants::_getInstanceByObjId($a_obj_id);
131
132            case 'grp':
133                include_once './Modules/Group/classes/class.ilGroupParticipants.php';
134                return ilGroupParticipants::_getInstanceByObjId($a_obj_id);
135
136            case 'sess':
137                include_once './Modules/Session/classes/class.ilSessionParticipants.php';
138                return ilSessionParticipants::_getInstanceByObjId($a_obj_id);
139            case 'lso':
140                return ilLearningSequenceParticipants::_getInstanceByObjId($a_obj_id);
141            default:
142                $GLOBALS['DIC']->logger()->mmbr()->logStack(ilLogLevel::WARNING);
143                $GLOBALS['DIC']->logger()->mmbr()->warning(': Invalid obj_id given: ' . $a_obj_id);
144                throw new InvalidArgumentException('Invalid obj id given');
145        }
146    }
147
148    /**
149     * Get component name
150     * Used for raising events
151     */
152    protected function getComponent()
153    {
154        return $this->component;
155    }
156
157
158
159    /**
160     * Check if (current) user has access to the participant list
161     * @param int $a_obj
162     * @param int $a_usr_id
163     */
164    public static function hasParticipantListAccess($a_obj_id, $a_usr_id = null)
165    {
166        global $DIC;
167
168        $access = $DIC->access();
169
170        if (!$a_usr_id) {
171            $a_usr_id = $GLOBALS['DIC']['ilUser']->getId();
172        }
173
174        // if write access granted => return true
175        $refs = ilObject::_getAllReferences($a_obj_id);
176        $ref_id = end($refs);
177
178        if ($access->checkAccess('manage_members', '', $ref_id)) {
179            return true;
180        }
181        $part = self::getInstance($ref_id);
182        if ($part->isAssigned($a_usr_id)) {
183            if ($part->getType() == 'crs') {
184                if (!ilObjCourse::lookupShowMembersEnabled($a_obj_id)) {
185                    return false;
186                }
187            }
188            if ($part->getType() == 'grp') {
189                if (!ilObjGroup::lookupShowMembersEnabled($a_obj_id)) {
190                    return false;
191                }
192            }
193            return true;
194        }
195        // User is not assigned to course/group => no read access
196        return false;
197    }
198
199
200    /**
201     * Get user membership assignments by type
202     *
203     * @param int[] $a_user_ids
204     * @param string[] $a_type
205     * @param bool $a_only_member_roles
206     */
207    public static function getUserMembershipAssignmentsByType($a_user_ids, $a_type, $a_only_member_roles)
208    {
209        global $DIC;
210
211        $logger = $DIC->logger()->mmbr();
212        $ilDB = $DIC->database();
213
214        if ($a_only_member_roles) {
215            $j2 = "JOIN object_data obd2 ON (ua.rol_id = obd2.obj_id) ";
216            $a2 = 'AND obd2.title = ' . $ilDB->concat(
217                array(
218                        array($ilDB->quote('il_', 'text')),
219                        array('obd.type'),
220                        array($ilDB->quote('_member_', 'text')),
221                        array('obr.ref_id'),
222                    ),
223                false
224            );
225        }
226
227        $query = "SELECT DISTINCT obd.obj_id,obr.ref_id,ua.usr_id FROM rbac_ua ua " .
228            "JOIN rbac_fa fa ON ua.rol_id = fa.rol_id " .
229            "JOIN object_reference obr ON fa.parent = obr.ref_id " .
230            "JOIN object_data obd ON obr.obj_id = obd.obj_id " .
231            $j2 .
232            "WHERE " . $ilDB->in("obd.type", $a_type, false, "text") .
233            "AND fa.assign = 'y' " .
234            'AND ' . $ilDB->in('ua.usr_id', $a_user_ids, false, 'integer') . ' ' .
235            $a2;
236
237        $logger->debug($query);
238
239
240        $obj_ids = [];
241        $res = $ilDB->query($query);
242        while ($row = $ilDB->fetchObject($res)) {
243            $obj_ids[$row->obj_id][] = $row->usr_id;
244        }
245
246        $logger->dump($obj_ids, \ilLogLevel::DEBUG);
247
248        return $obj_ids;
249    }
250
251    /**
252     * get membership by type
253     * Get course or group membership
254     *
255     * @access public
256     * @param int $a_usr_id usr_id
257     * @param string|array $a_type crs or grp | array of strings
258     * @param bool $a_only_member_role
259     * @return
260     * @static
261     */
262    public static function _getMembershipByType($a_usr_id, $a_type, $a_only_member_role = false)
263    {
264        global $DIC;
265
266        $ilDB = $DIC['ilDB'];
267
268        if (!is_array($a_type)) {
269            $a_type = array($a_type);
270        }
271
272        // this will also dismiss local roles!
273        if ($a_only_member_role) {
274            $j2 = "JOIN object_data obd2 ON (ua.rol_id = obd2.obj_id) ";
275            $a2 = 'AND obd2.title = ' . $ilDB->concat(
276                array(
277                    array($ilDB->quote('il_', 'text')),
278                    array('obd.type'),
279                    array($ilDB->quote('_member_', 'text')),
280                    array('obr.ref_id'),
281                ),
282                false
283            );
284        }
285
286        // #14290 - no role folder anymore
287        $query = "SELECT DISTINCT obd.obj_id,obr.ref_id FROM rbac_ua ua " .
288            "JOIN rbac_fa fa ON ua.rol_id = fa.rol_id " .
289            "JOIN object_reference obr ON fa.parent = obr.ref_id " .
290            "JOIN object_data obd ON obr.obj_id = obd.obj_id " .
291            $j2 .
292            "WHERE " . $ilDB->in("obd.type", $a_type, false, "text") .
293            "AND fa.assign = 'y' " .
294            "AND ua.usr_id = " . $ilDB->quote($a_usr_id, 'integer') . " " .
295            $a2;
296        $res = $ilDB->query($query);
297        while ($row = $ilDB->fetchObject($res)) {
298            $ref_ids[] = $row->obj_id;
299        }
300
301        return $ref_ids ? $ref_ids : array();
302    }
303
304
305
306    /**
307     * Static function to check if a user is a participant of the container object
308     *
309     * @access public
310     * @param int ref_id
311     * @param int user id
312     * @static
313     */
314    public static function _isParticipant($a_ref_id, $a_usr_id)
315    {
316        global $DIC;
317
318        $rbacreview = $DIC['rbacreview'];
319
320        $local_roles = $rbacreview->getRolesOfRoleFolder($a_ref_id, false);
321
322        return $rbacreview->isAssignedToAtLeastOneGivenRole($a_usr_id, $local_roles);
323    }
324
325    /**
326     * Lookup the number of participants (crs admins, tutors, members, grp admins, members)
327     *
328     * @global ilRbacReview $rbacreview
329     * @param int $a_ref_id
330     *
331     */
332    public static function lookupNumberOfParticipants($a_ref_id)
333    {
334        global $DIC;
335
336        $rbacreview = $DIC['rbacreview'];
337
338        $lroles = $rbacreview->getRolesOfRoleFolder($a_ref_id, false);
339        return $rbacreview->getNumberOfAssignedUsers($lroles);
340    }
341
342    /**
343     * Lookup number of members
344     * @global ilRbacReview $rbacreview
345     * @global <type> $ilObjDataCache
346     * @param <type> $a_ref_id
347     * @return int
348     */
349    public static function lookupNumberOfMembers($a_ref_id)
350    {
351        global $DIC;
352
353        $rbacreview = $DIC->rbac()->review();
354        $ilObjDataCache = $DIC['ilObjDataCache'];
355
356        $has_policies = $rbacreview->getLocalPolicies($a_ref_id);
357
358        if (!$has_policies) {
359            return 0;
360        }
361        $lroles = $rbacreview->getRolesOfRoleFolder($a_ref_id, false);
362
363        $memberRoles = array();
364        foreach ($lroles as $role_id) {
365            $title = $ilObjDataCache->lookupTitle($role_id);
366            switch (substr($title, 0, 8)) {
367                case 'il_crs_a':
368                case 'il_crs_t':
369                case 'il_grp_a':
370                    break;
371
372                default:
373                    $memberRoles[] = $role_id;
374                    break;
375            }
376        }
377        return $rbacreview->getNumberOfAssignedUsers($memberRoles);
378    }
379
380
381    /**
382     * Check if user is blocked
383     *
384     * @access public
385     * @static
386     *
387     * @param int course id
388     * @param int usr_id
389     */
390    public static function _isBlocked($a_obj_id, $a_usr_id)
391    {
392        global $DIC;
393
394        $ilDB = $DIC['ilDB'];
395
396        $query = "SELECT * FROM obj_members " .
397            "WHERE obj_id = " . $ilDB->quote($a_obj_id, 'integer') . " " .
398            "AND usr_id = " . $ilDB->quote($a_usr_id, 'integer') . " " .
399            "AND blocked = " . $ilDB->quote(1, 'integer');
400        $res = $ilDB->query($query);
401        return $res->numRows() ? true : false;
402    }
403
404    /**
405     * Check if user has passed course
406     *
407     * @access public
408     * @static
409     *
410     * @param int obj_id
411     * @param int user id
412     */
413    public static function _hasPassed($a_obj_id, $a_usr_id)
414    {
415        global $DIC;
416
417        $ilDB = $DIC['ilDB'];
418
419        $query = "SELECT * FROM obj_members " .
420            "WHERE obj_id = " . $ilDB->quote($a_obj_id, 'integer') . " " .
421            "AND usr_id = " . $ilDB->quote($a_usr_id, 'integer') . " " .
422            "AND passed = '1'";
423        $res = $ilDB->query($query);
424        return $res->numRows() ? true : false;
425    }
426
427    /**
428     * Delete all entries
429     * Normally called for course deletion
430     *
431     * @access public
432     * @static
433     *
434     * @param int obj_id
435     */
436    public static function _deleteAllEntries($a_obj_id)
437    {
438        global $DIC;
439
440        $ilDB = $DIC['ilDB'];
441
442        $query = "DELETE FROM obj_members " .
443            "WHERE obj_id = " . $ilDB->quote($a_obj_id, 'integer') . " ";
444        $res = $ilDB->manipulate($query);
445
446        $query = "DELETE FROM il_subscribers " .
447            "WHERE obj_id = " . $ilDB->quote($a_obj_id, 'integer') . "";
448        $res = $ilDB->manipulate($query);
449
450        $query = 'DELETE FROM crs_waiting_list ' .
451                'WHERE obj_id = ' . $ilDB->quote($a_obj_id, 'integer');
452        $ilDB->manipulate($query);
453
454        return true;
455    }
456
457    /**
458     * Delete user data
459     *
460     * @access public
461     * @static
462     *
463     * @param int user id
464     */
465    public static function _deleteUser($a_usr_id)
466    {
467        global $DIC;
468
469        $ilDB = $DIC['ilDB'];
470
471        $query = "DELETE FROM obj_members WHERE usr_id = " . $ilDB->quote($a_usr_id, 'integer') . "";
472        $res = $ilDB->manipulate($query);
473
474        $query = "DELETE FROM il_subscribers WHERE usr_id = " . $ilDB->quote($a_usr_id, 'integer') . "";
475        $res = $ilDB->manipulate($query);
476
477        include_once './Modules/Course/classes/class.ilCourseWaitingList.php';
478        ilCourseWaitingList::_deleteUser($a_usr_id);
479    }
480
481    public static function getDefaultMemberRole($a_ref_id)
482    {
483        global $DIC;
484
485        $ilCtrl = $DIC['ilCtrl'];
486
487        $obj_id = ilObject::_lookupObjId($a_ref_id);
488        $type = ilObject::_lookupType($obj_id);
489
490        if (!in_array($type, array('crs','grp'))) {
491            return 0;
492        }
493
494        global $DIC;
495
496        $rbacreview = $DIC['rbacreview'];
497
498
499        $roles = $rbacreview->getRolesOfRoleFolder($a_ref_id, false);
500
501        foreach ($roles as $role) {
502            $title = ilObject::_lookupTitle($role);
503            if (substr($title, 0, 13) == ('il_' . $type . '_member')) {
504                return $role;
505            }
506        }
507        return 0;
508    }
509
510    /**
511     * get current obj_id
512     * @return type
513     */
514    public function getObjId()
515    {
516        return $this->obj_id;
517    }
518
519    /**
520     * Get object type
521     * @return string obj_type
522     */
523    public function getType()
524    {
525        return $this->type;
526    }
527
528    /**
529     * Get admin, tutor which have notification enabled
530     *
531     * @access public
532     * @return array array of user ids
533     */
534    public function getNotificationRecipients()
535    {
536        global $DIC;
537
538        $ilDB = $DIC['ilDB'];
539
540        $query = "SELECT * FROM obj_members " .
541            "WHERE notification = 1 " .
542            "AND obj_id = " . $ilDB->quote($this->obj_id) . " ";
543        $res = $ilDB->query($query);
544        while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
545            if ($this->isAdmin($row->usr_id) or $this->isTutor($row->usr_id)) {
546                $recp[] = $row->usr_id;
547            }
548        }
549        return $recp ? $recp : array();
550    }
551
552    /**
553     * Get number of members (not participants)
554     *
555     * @access public
556     *
557     */
558    public function getCountMembers()
559    {
560        return count($this->members);
561    }
562
563    /**
564     * Get number of participants
565     *
566     * @access public
567     *
568     */
569    public function getCountParticipants()
570    {
571        return count($this->participants);
572    }
573
574
575
576
577    /**
578     * Get all participants ids
579     *
580     * @access public
581     * @return array array of user ids
582     */
583    public function getParticipants()
584    {
585        return $this->participants ? $this->participants : array();
586    }
587
588    /**
589     * Get all members ids (admins and tutors are not members)
590     * Use get participants to fetch all
591     *
592     * @access public
593     * @return array array of user ids
594     */
595    public function getMembers()
596    {
597        return $this->members ? $this->members : array();
598    }
599    /**
600     * Get all admins ids
601     *
602     * @access public
603     * @return array array of user ids
604     */
605    public function getAdmins()
606    {
607        return $this->admins ? $this->admins : array();
608    }
609
610    /**
611     * Get number of admins
612     * @return
613     */
614    public function getCountAdmins()
615    {
616        return count($this->getAdmins());
617    }
618
619
620    /**
621     * Get all tutors ids
622     *
623     * @access public
624     * @return array array of user ids
625     */
626    public function getTutors()
627    {
628        return $this->tutors ? $this->tutors : array();
629    }
630
631    /**
632     * is user admin
633     *
634     * @access public
635     * @param int usr_id
636     *
637     */
638    public function isAdmin($a_usr_id)
639    {
640        return in_array($a_usr_id, $this->admins) ? true : false;
641    }
642
643    /**
644     * is user tutor
645     *
646     * @access public
647     * @param int usr_id
648     *
649     */
650    public function isTutor($a_usr_id)
651    {
652        return in_array($a_usr_id, $this->tutors) ? true : false;
653    }
654
655    /**
656     * is user member
657     *
658     * @access public
659     * @param int usr_id
660     *
661     */
662    public function isMember($a_usr_id)
663    {
664        return in_array($a_usr_id, $this->members) ? true : false;
665    }
666
667
668
669
670    /**
671     * check if user is assigned
672     *
673     * @access public
674     * @param
675     *
676     */
677    public function isAssigned($a_usr_id)
678    {
679        return in_array($a_usr_id, $this->participants);
680    }
681
682    /**
683     * Check if user is last admin
684     * @param int $a_usr_id
685     * @return bool
686     */
687    public function isLastAdmin($a_usr_id)
688    {
689        return in_array($a_usr_id, $this->getAdmins()) and count($this->getAdmins()) == 1;
690    }
691
692
693    /**
694     * Get course roles
695     *
696     * @access public
697     * @param
698     *
699     */
700    public function getRoles()
701    {
702        return $this->roles ? $this->roles : array();
703    }
704
705    /**
706     * Get assigned roles
707     *
708     * @access public
709     * @param int user_id
710     *
711     */
712    public function getAssignedRoles($a_usr_id)
713    {
714        global $DIC;
715
716        $rbacreview = $DIC['rbacreview'];
717
718        foreach ($this->roles as $role) {
719            if ($rbacreview->isAssigned($a_usr_id, $role)) {
720                $assigned[] = $role;
721            }
722        }
723        return $assigned ? $assigned : array();
724    }
725
726    /**
727     * Update role assignments
728     *
729     * @access public
730     * @param int usr_id
731     * @param array array of new roles
732     *
733     */
734    public function updateRoleAssignments($a_usr_id, $a_roles)
735    {
736        global $DIC;
737
738        $rbacreview = $DIC['rbacreview'];
739        $rbacadmin = $DIC['rbacadmin'];
740
741        $roles = $a_roles ? $a_roles : array();
742
743        foreach ($this->getRoles() as $role_id) {
744            if ($rbacreview->isAssigned($a_usr_id, $role_id)) {
745                if (!in_array($role_id, $roles)) {
746                    $rbacadmin->deassignUser($role_id, $a_usr_id);
747                }
748            } else {
749                if (in_array($role_id, $roles)) {
750                    $rbacadmin->assignUser($role_id, $a_usr_id);
751                }
752            }
753        }
754        $rbacreview->clearCaches();
755        $this->readParticipants();
756        $this->readParticipantsStatus();
757    }
758
759    /**
760     * Check if user for deletion are last admins
761     *
762     * @access public
763     * @param array array of user ids for deletion
764     *
765     */
766    public function checkLastAdmin($a_usr_ids)
767    {
768        foreach ($this->getAdmins() as $admin_id) {
769            if (!in_array($admin_id, $a_usr_ids)) {
770                return true;
771            }
772        }
773        return false;
774    }
775
776    /**
777     * Check if user is blocked
778     *
779     * @access public
780     * @param int user_id
781     *
782     */
783    public function isBlocked($a_usr_id)
784    {
785        if (isset($this->participants_status[$a_usr_id])) {
786            return $this->participants_status[$a_usr_id]['blocked'] ? true : false;
787        }
788        return false;
789    }
790
791    /**
792     * Check if user has passed course
793     *
794     * @access public
795     * @param int user_id
796     *
797     */
798    public function hasPassed($a_usr_id)
799    {
800        if (isset($this->participants_status[$a_usr_id])) {
801            return $this->participants_status[$a_usr_id]['passed'] ? true : false;
802        }
803        return false;
804    }
805
806    /**
807     * Drop user from all roles
808     *
809     * @access public
810     * @param int usr_id
811     *
812     */
813    public function delete($a_usr_id)
814    {
815        global $DIC;
816
817        $rbacadmin = $DIC['rbacadmin'];
818        $ilDB = $DIC['ilDB'];
819
820        $this->dropDesktopItem($a_usr_id);
821        foreach ($this->roles as $role_id) {
822            $rbacadmin->deassignUser($role_id, $a_usr_id);
823        }
824
825        $query = "DELETE FROM obj_members " .
826            "WHERE usr_id = " . $ilDB->quote($a_usr_id, 'integer') . " " .
827            "AND obj_id = " . $ilDB->quote($this->obj_id, 'integer');
828        $res = $ilDB->manipulate($query);
829
830        $this->readParticipants();
831        $this->readParticipantsStatus();
832
833        $GLOBALS['DIC']['ilAppEventHandler']->raise(
834            $this->getComponent(),
835            "deleteParticipant",
836            array(
837                    'obj_id' => $this->obj_id,
838                    'usr_id' => $a_usr_id)
839        );
840
841        return true;
842    }
843
844    /**
845     * Update blocked status
846     *
847     * @access public
848     * @param int usr_id
849     * @param bool blocked
850     *
851     */
852    public function updateBlocked($a_usr_id, $a_blocked)
853    {
854        global $DIC;
855
856        $ilDB = $DIC['ilDB'];
857
858        $this->participants_status[$a_usr_id]['blocked'] = (int) $a_blocked;
859
860        $query = "SELECT * FROM obj_members " .
861        "WHERE obj_id = " . $ilDB->quote($this->obj_id, 'integer') . " " .
862        "AND usr_id = " . $ilDB->quote($a_usr_id, 'integer');
863        $res = $ilDB->query($query);
864        if ($res->numRows()) {
865            $query = "UPDATE obj_members SET " .
866                "blocked = " . $ilDB->quote((int) $a_blocked, 'integer') . " " .
867                "WHERE obj_id = " . $ilDB->quote($this->obj_id, 'integer') . " " .
868                "AND usr_id = " . $ilDB->quote($a_usr_id, 'integer');
869        } else {
870            $query = "INSERT INTO obj_members (blocked,obj_id,usr_id,notification,passed) " .
871                "VALUES ( " .
872                $ilDB->quote((int) $a_blocked, 'integer') . ", " .
873                $ilDB->quote($this->obj_id, 'integer') . ", " .
874                $ilDB->quote($a_usr_id, 'integer') . ", " .
875                $ilDB->quote(0, 'integer') . ", " .
876                $ilDB->quote(0, 'integer') .
877                ")";
878        }
879        $res = $ilDB->manipulate($query);
880        return true;
881    }
882
883    // cognos-blu-patch: begin
884    /**
885     * Update contact setting
886     * @global type $ilDB
887     * @param type $a_usr_id
888     * @param type $a_contact
889     * @return boolean
890     */
891    public function updateContact($a_usr_id, $a_contact)
892    {
893        global $DIC;
894
895        $ilDB = $DIC['ilDB'];
896
897        $ilDB->manipulate(
898            'UPDATE obj_members SET ' .
899                'contact = ' . $ilDB->quote($a_contact, 'integer') . ' ' .
900                'WHERE obj_id = ' . $ilDB->quote($this->obj_id, 'integer') . ' ' .
901                'AND usr_id = ' . $ilDB->quote($a_usr_id, 'integer')
902        );
903
904        $this->participants_status[$a_usr_id]['contact'] = $a_contact;
905        return true;
906    }
907
908    /**
909     * get user ids which are confirgured as contact
910     * @return array
911     */
912    public function getContacts()
913    {
914        $contacts = array();
915        foreach ((array) $this->participants_status as $usr_id => $status) {
916            if ($status['contact']) {
917                $contacts[] = $usr_id;
918            }
919        }
920        return $contacts;
921    }
922
923
924    // cognos-blu-patch: end
925
926    /**
927     * Update notification status
928     *
929     * @access public
930     * @param int usr_id
931     * @param bool passed
932     *
933     */
934    public function updateNotification($a_usr_id, $a_notification)
935    {
936        global $DIC;
937
938        $ilDB = $DIC['ilDB'];
939
940        $this->participants_status[$a_usr_id]['notification'] = (int) $a_notification;
941
942        $query = "SELECT * FROM obj_members " .
943        "WHERE obj_id = " . $ilDB->quote($this->obj_id, 'integer') . " " .
944        "AND usr_id = " . $ilDB->quote($a_usr_id, 'integer');
945        $res = $ilDB->query($query);
946        if ($res->numRows()) {
947            $query = "UPDATE obj_members SET " .
948                "notification = " . $ilDB->quote((int) $a_notification, 'integer') . " " .
949                "WHERE obj_id = " . $ilDB->quote($this->obj_id, 'integer') . " " .
950                "AND usr_id = " . $ilDB->quote($a_usr_id, 'integer');
951        } else {
952            $query = "INSERT INTO obj_members (notification,obj_id,usr_id,passed,blocked) " .
953                "VALUES ( " .
954                $ilDB->quote((int) $a_notification, 'integer') . ", " .
955                $ilDB->quote($this->obj_id, 'integer') . ", " .
956                $ilDB->quote($a_usr_id, 'integer') . ", " .
957                $ilDB->quote(0, 'integer') . ", " .
958                $ilDB->quote(0, 'integer') .
959                ")";
960        }
961        $res = $ilDB->manipulate($query);
962        return true;
963    }
964
965
966
967
968    /**
969     * Add user to object
970     *
971     * @access public
972     * @param int user id
973     * @param int role IL_CRS_ADMIN || IL_CRS_TUTOR || IL_CRS_MEMBER
974     *
975     */
976    public function add($a_usr_id, $a_role)
977    {
978        global $DIC;
979
980        $rbacadmin = $DIC['rbacadmin'];
981        $ilAppEventHandler = $DIC['ilAppEventHandler'];
982
983        if ($this->isAssigned($a_usr_id)) {
984            return false;
985        }
986
987        switch ($a_role) {
988            case IL_CRS_ADMIN:
989                $this->admins[] = $a_usr_id;
990                break;
991
992            case IL_CRS_TUTOR:
993                $this->tutors[] = $a_usr_id;
994                break;
995
996            case IL_CRS_MEMBER:
997                $this->members[] = $a_usr_id;
998                break;
999
1000            case IL_GRP_ADMIN:
1001                $this->admins[] = $a_usr_id;
1002                break;
1003
1004            case IL_GRP_MEMBER:
1005                $this->members[] = $a_usr_id;
1006                break;
1007
1008            case IL_LSO_ADMIN:
1009                $this->admins[] = $a_usr_id;
1010                break;
1011
1012            case IL_LSO_MEMBER:
1013                $this->members[] = $a_usr_id;
1014                break;
1015
1016            case IL_SESS_MEMBER:
1017                $this->members[] = $a_usr_id;
1018                break;
1019        }
1020
1021        $this->participants[] = $a_usr_id;
1022        $rbacadmin->assignUser($this->role_data[$a_role], $a_usr_id);
1023
1024        // Delete subscription request
1025        $this->deleteSubscriber($a_usr_id);
1026
1027        include_once './Services/Membership/classes/class.ilWaitingList.php';
1028        ilWaitingList::deleteUserEntry($a_usr_id, $this->obj_id);
1029
1030        $ilAppEventHandler->raise(
1031            $this->getComponent(),
1032            "addParticipant",
1033            array(
1034                    'obj_id' => $this->obj_id,
1035                    'usr_id' => $a_usr_id,
1036                    'role_id' => $a_role)
1037        );
1038        return true;
1039    }
1040
1041
1042    /**
1043     * Delete users
1044     *
1045     * @access public
1046     * @param array user ids
1047     *
1048     */
1049    public function deleteParticipants($a_user_ids)
1050    {
1051        foreach ($a_user_ids as $user_id) {
1052            $this->delete($user_id);
1053        }
1054        return true;
1055    }
1056
1057    /**
1058     * Add desktop item
1059     *
1060     * @access public
1061     * @param int usr_id
1062     *
1063     */
1064    public function addDesktopItem($a_usr_id)
1065    {
1066        if (!ilObjUser::_isDesktopItem($a_usr_id, $this->ref_id, $this->type)) {
1067            ilObjUser::_addDesktopItem($a_usr_id, $this->ref_id, $this->type);
1068        }
1069        return true;
1070    }
1071
1072    /**
1073     * Drop desktop item
1074     *
1075     * @access public
1076     * @param int usr_id
1077     *
1078     */
1079    public function dropDesktopItem($a_usr_id)
1080    {
1081        if (ilObjUser::_isDesktopItem($a_usr_id, $this->ref_id, $this->type)) {
1082            ilObjUser::_dropDesktopItem($a_usr_id, $this->ref_id, $this->type);
1083        }
1084
1085        return true;
1086    }
1087
1088
1089
1090    /**
1091     * check if notification is enabled
1092     *
1093     * @access public
1094     * @param
1095     *
1096     */
1097    public function isNotificationEnabled($a_usr_id)
1098    {
1099        if (isset($this->participants_status[$a_usr_id])) {
1100            return $this->participants_status[$a_usr_id]['notification'] ? true : false;
1101        }
1102        return false;
1103    }
1104
1105    // cognos-blu-patch: begin
1106    /**
1107     * Check if user is contact
1108     * @param int usr_id
1109     */
1110    public function isContact($a_usr_id)
1111    {
1112        if (isset($this->participants_status[$a_usr_id])) {
1113            return (bool) $this->participants_status[$a_usr_id]['contact'];
1114        }
1115        return false;
1116    }
1117    // cognos-blu-patch: end
1118
1119
1120    /**
1121     * Get role id of auto generated role type
1122     * @param type $a_role_type
1123     */
1124    public function getAutoGeneratedRoleId($a_role_type)
1125    {
1126        if (array_key_exists($a_role_type, $this->role_data)) {
1127            return $this->role_data[$a_role_type];
1128        }
1129
1130        return 0;
1131    }
1132
1133
1134    /**
1135     * Read participants
1136     *
1137     * @access private
1138     * @param
1139     *
1140     */
1141    protected function readParticipants()
1142    {
1143        global $DIC;
1144
1145        $rbacreview = $DIC['rbacreview'];
1146        $ilObjDataCache = $DIC['ilObjDataCache'];
1147        $ilLog = $DIC['ilLog'];
1148
1149        $GLOBALS['DIC']['rbacreview']->clearCaches();
1150        $this->roles = $rbacreview->getRolesOfRoleFolder($this->ref_id, false);
1151
1152        $users = array();
1153        $this->participants = array();
1154        $this->members = $this->admins = $this->tutors = array();
1155
1156        $additional_roles = [];
1157        $auto_generated_roles = [];
1158        foreach ($this->roles as $role_id) {
1159            $title = $ilObjDataCache->lookupTitle($role_id);
1160            switch (substr($title, 0, 8)) {
1161                case 'il_crs_m':
1162                    $auto_generated_roles[$role_id] = IL_ROLE_POSITION_MEMBER;
1163                    $this->role_data[IL_CRS_MEMBER] = $role_id;
1164                    $this->participants = array_unique(array_merge($assigned = $rbacreview->assignedUsers($role_id), $this->participants));
1165                    $this->members = array_unique(array_merge($assigned, $this->members));
1166                    $this->role_assignments[$role_id] = $assigned;
1167                    break;
1168
1169                case 'il_crs_a':
1170                    $auto_generated_roles[$role_id] = IL_ROLE_POSITION_ADMIN;
1171                    $this->role_data[IL_CRS_ADMIN] = $role_id;
1172                    $this->participants = array_unique(array_merge($assigned = $rbacreview->assignedUsers($role_id), $this->participants));
1173                    $this->admins = $rbacreview->assignedUsers($role_id);
1174                    $this->role_assignments[$role_id] = $assigned;
1175                    break;
1176
1177                case 'il_crs_t':
1178                    $auto_generated_roles[$role_id] = IL_ROLE_POSITION_TUTOR;
1179                    $this->role_data[IL_CRS_TUTOR] = $role_id;
1180                    $this->participants = array_unique(array_merge($assigned = $rbacreview->assignedUsers($role_id), $this->participants));
1181                    $this->tutors = $rbacreview->assignedUsers($role_id);
1182                    $this->role_assignments[$role_id] = $assigned;
1183                    break;
1184
1185                case 'il_grp_a':
1186                    $auto_generated_roles[$role_id] = IL_ROLE_POSITION_ADMIN;
1187                    $this->role_data[IL_GRP_ADMIN] = $role_id;
1188                    $this->participants = array_unique(array_merge($assigned = $rbacreview->assignedUsers($role_id), $this->participants));
1189                    $this->admins = $rbacreview->assignedUsers($role_id);
1190                    $this->role_assignments[$role_id] = $assigned;
1191                    break;
1192
1193                case 'il_grp_m':
1194                    $auto_generated_roles[$role_id] = IL_ROLE_POSITION_MEMBER;
1195                    $this->role_data[IL_GRP_MEMBER] = $role_id;
1196                    $this->participants = array_unique(array_merge($assigned = $rbacreview->assignedUsers($role_id), $this->participants));
1197                    $this->members = $rbacreview->assignedUsers($role_id);
1198                    $this->role_assignments[$role_id] = $assigned;
1199                    break;
1200
1201                case 'il_sess_':
1202                    $this->role_data[IL_SESS_MEMBER] = $role_id;
1203                    $this->participants = array_unique(array_merge($assigned = $rbacreview->assignedUsers($role_id), $this->participants));
1204                    $this->members = $rbacreview->assignedUsers($role_id);
1205                    break;
1206
1207                case 'il_lso_m':
1208                    $auto_generated_roles[$role_id] = IL_ROLE_POSITION_MEMBER;
1209                    $this->role_data[IL_LSO_MEMBER] = $role_id;
1210                    $this->participants = array_unique(array_merge($assigned = $rbacreview->assignedUsers($role_id), $this->participants));
1211                    $this->members = $rbacreview->assignedUsers($role_id);
1212                    $this->role_assignments[$role_id] = $assigned;
1213                    break;
1214
1215                case 'il_lso_a':
1216                    $auto_generated_roles[$role_id] = IL_ROLE_POSITION_ADMIN;
1217                    $this->role_data[IL_LSO_ADMIN] = $role_id;
1218                    $this->participants = array_unique(array_merge($assigned = $rbacreview->assignedUsers($role_id), $this->participants));
1219                    $this->admins = $rbacreview->assignedUsers($role_id);
1220                    $this->role_assignments[$role_id] = $assigned;
1221                    break;
1222
1223                default:
1224                    $additional_roles[$role_id] = $title;
1225                    $this->participants = array_unique(array_merge($assigned = $rbacreview->assignedUsers($role_id), $this->participants));
1226                    $this->members = array_unique(array_merge($assigned, $this->members));
1227                    $this->role_assignments[$role_id] = $assigned;
1228                    break;
1229            }
1230        }
1231        asort($auto_generated_roles);
1232        asort($additional_roles);
1233        $this->roles_sorted = $auto_generated_roles + $additional_roles;
1234    }
1235
1236    /**
1237     * Read status of participants (blocked, notification, passed)
1238     *
1239     * @access private
1240     * @param
1241     *
1242     */
1243    protected function readParticipantsStatus()
1244    {
1245        global $DIC;
1246
1247        $ilDB = $DIC['ilDB'];
1248
1249        $query = "SELECT * FROM obj_members " .
1250            "WHERE obj_id = " . $ilDB->quote($this->obj_id, 'integer') . " ";
1251        $res = $ilDB->query($query);
1252        $this->participants_status = array();
1253        while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1254            $this->participants_status[$row->usr_id]['blocked'] = $row->blocked;
1255            $this->participants_status[$row->usr_id]['notification'] = $row->notification;
1256            $this->participants_status[$row->usr_id]['passed'] = $row->passed;
1257            // cognos-blu-patch: begin
1258            $this->participants_status[$row->usr_id]['contact'] = $row->contact;
1259            // cognos-blu-patch: end
1260        }
1261    }
1262
1263    /**
1264     * Check grouping membership
1265     *
1266     * @access public
1267     * @param
1268     *
1269     */
1270    public function isGroupingMember($a_usr_id, $a_field = '')
1271    {
1272        global $DIC;
1273
1274        $rbacreview = $DIC['rbacreview'];
1275        $ilObjDataCache = $DIC['ilObjDataCache'];
1276        $ilDB = $DIC['ilDB'];
1277
1278        // Used for membership limitations -> check membership by given field
1279        if ($a_field) {
1280            include_once './Services/User/classes/class.ilObjUser.php';
1281
1282            $tmp_user = &ilObjectFactory::getInstanceByObjId($a_usr_id);
1283            switch ($a_field) {
1284                case 'login':
1285                    $and = "AND login = " . $ilDB->quote($tmp_user->getLogin(), 'text') . " ";
1286                    break;
1287                case 'email':
1288                    $and = "AND email = " . $ilDB->quote($tmp_user->getEmail(), 'text') . " ";
1289                    break;
1290                case 'matriculation':
1291                    $and = "AND matriculation = " . $ilDB->quote($tmp_user->getMatriculation(), 'text') . " ";
1292                    break;
1293
1294                default:
1295                    $and = "AND usr_id = " . $ilDB->quote($a_usr_id, 'integer') . " ";
1296                    break;
1297            }
1298
1299            if (!$this->getParticipants()) {
1300                return false;
1301            }
1302
1303            $query = "SELECT * FROM usr_data ud " .
1304                "WHERE " . $ilDB->in('usr_id', $this->getParticipants(), false, 'integer') . " " .
1305                $and;
1306
1307            $res = $ilDB->query($query);
1308            return $res->numRows() ? true : false;
1309        }
1310    }
1311
1312    public static function lookupSubscribers($a_obj_id)
1313    {
1314        global $DIC;
1315
1316        $ilDB = $DIC['ilDB'];
1317
1318        $subscribers = array();
1319        $query = "SELECT usr_id FROM il_subscribers " .
1320            "WHERE obj_id = " . $ilDB->quote($a_obj_id, 'integer') . " " .
1321            "ORDER BY sub_time ";
1322
1323        $res = $ilDB->query($query);
1324        while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1325            $subscribers[] = $row->usr_id;
1326        }
1327        return $subscribers;
1328    }
1329
1330    /**
1331     * get all subscribers
1332     *
1333     * @access public
1334     */
1335    public function getSubscribers()
1336    {
1337        $this->readSubscribers();
1338
1339        return $this->subscribers;
1340    }
1341
1342
1343    /**
1344     * get number of subscribers
1345     *
1346     * @access public
1347     */
1348    public function getCountSubscribers()
1349    {
1350        return count($this->getSubscribers());
1351    }
1352
1353    /**
1354     * get subscriber data
1355     *
1356     * @access public
1357     */
1358    public function getSubscriberData($a_usr_id)
1359    {
1360        return $this->readSubscriberData($a_usr_id);
1361    }
1362
1363
1364
1365    /**
1366     * Assign subscribers
1367     *
1368     * @access public
1369     */
1370    public function assignSubscribers($a_usr_ids)
1371    {
1372        if (!is_array($a_usr_ids) or !count($a_usr_ids)) {
1373            return false;
1374        }
1375        foreach ($a_usr_ids as $id) {
1376            if (!$this->assignSubscriber($id)) {
1377                return false;
1378            }
1379        }
1380        return true;
1381    }
1382
1383    /**
1384     * Assign subscriber
1385     *
1386     * @access public
1387     */
1388    public function assignSubscriber($a_usr_id)
1389    {
1390        global $DIC;
1391
1392        $ilErr = $DIC['ilErr'];
1393
1394        $ilErr->setMessage("");
1395        if (!$this->isSubscriber($a_usr_id)) {
1396            $ilErr->appendMessage($this->lng->txt("crs_user_notsubscribed"));
1397
1398            return false;
1399        }
1400        if ($this->isAssigned($a_usr_id)) {
1401            $tmp_obj = ilObjectFactory::getInstanceByObjId($a_usr_id);
1402            $ilErr->appendMessage($tmp_obj->getLogin() . ": " . $this->lng->txt("crs_user_already_assigned"));
1403
1404            return false;
1405        }
1406
1407        if (!$tmp_obj = &ilObjectFactory::getInstanceByObjId($a_usr_id)) {
1408            $ilErr->appendMessage($this->lng->txt("crs_user_not_exists"));
1409
1410            return false;
1411        }
1412
1413        // TODO: must be group or course member role
1414        if ($this instanceof ilCourseParticipants) {
1415            $this->add($tmp_obj->getId(), IL_CRS_MEMBER);
1416        }
1417        if ($this instanceof ilGroupParticipants) {
1418            $this->add($tmp_obj->getId(), IL_GRP_MEMBER);
1419        }
1420        if ($this instanceof ilLearningSequenceParticipants) {
1421            $this->add($tmp_obj->getId(), IL_LSO_MEMBER);
1422        }
1423        if ($this instanceof ilSessionParticipants) {
1424            $this->register($tmp_obj->getId());
1425        }
1426        $this->deleteSubscriber($a_usr_id);
1427        return true;
1428    }
1429
1430    /**
1431     * Assign subscriber
1432     *
1433     * @access public
1434     */
1435    public function autoFillSubscribers()
1436    {
1437        $this->readSubscribers();
1438
1439        $counter = 0;
1440        foreach ($this->subscribers as $subscriber) {
1441            if (!$this->assignSubscriber($subscriber)) {
1442                continue;
1443            } else {
1444                // TODO: notification
1445                #$this->sendNotification($this->NOTIFY_ACCEPT_SUBSCRIBER,$subscriber);
1446            }
1447            ++$counter;
1448        }
1449
1450        return $counter;
1451    }
1452
1453    /**
1454     * Add subscriber
1455     *
1456     * @access public
1457     */
1458    public function addSubscriber($a_usr_id)
1459    {
1460        global $DIC;
1461
1462        $ilDB = $DIC['ilDB'];
1463
1464        $query = "INSERT INTO il_subscribers (usr_id,obj_id,subject,sub_time) " .
1465            " VALUES (" .
1466            $ilDB->quote($a_usr_id, 'integer') . "," .
1467            $ilDB->quote($this->obj_id, 'integer') . ", " .
1468            $ilDB->quote('', 'text') . ", " .
1469            $ilDB->quote(time(), 'integer') .
1470            ")";
1471        $res = $ilDB->manipulate($query);
1472
1473        return true;
1474    }
1475
1476
1477    /**
1478     * Update subscription time
1479     *
1480     * @access public
1481     */
1482    public function updateSubscriptionTime($a_usr_id, $a_subtime)
1483    {
1484        global $DIC;
1485
1486        $ilDB = $DIC['ilDB'];
1487
1488        $query = "UPDATE il_subscribers " .
1489            "SET sub_time = " . $ilDB->quote($a_subtime, 'integer') . " " .
1490            "WHERE usr_id = " . $ilDB->quote($a_usr_id, 'integer') . " " .
1491            "AND obj_id = " . $ilDB->quote($this->obj_id, 'integer') . " ";
1492        $res = $ilDB->manipulate($query);
1493
1494        return true;
1495    }
1496
1497    /**
1498     * update subject
1499     *
1500     * @access public
1501     * @param
1502     * @return
1503     */
1504    public function updateSubject($a_usr_id, $a_subject)
1505    {
1506        global $DIC;
1507
1508        $ilDB = $DIC['ilDB'];
1509
1510        $query = "UPDATE il_subscribers " .
1511            "SET subject = " . $ilDB->quote($a_subject, 'text') . " " .
1512            "WHERE usr_id = " . $ilDB->quote($a_usr_id, 'integer') . " " .
1513            "AND obj_id = " . $ilDB->quote($this->obj_id, 'integer') . " ";
1514        $res = $ilDB->manipulate($query);
1515        return true;
1516    }
1517
1518
1519    /**
1520     * Delete subsciber
1521     *
1522     * @access public
1523     */
1524    public function deleteSubscriber($a_usr_id)
1525    {
1526        global $DIC;
1527
1528        $ilDB = $DIC['ilDB'];
1529
1530        $query = "DELETE FROM il_subscribers " .
1531            "WHERE usr_id = " . $ilDB->quote($a_usr_id, 'integer') . " " .
1532            "AND obj_id = " . $ilDB->quote($this->obj_id, 'integer') . " ";
1533        $res = $ilDB->manipulate($query);
1534
1535        return true;
1536    }
1537
1538
1539    /**
1540     * Delete subscibers
1541     *
1542     * @access public
1543     */
1544    public function deleteSubscribers($a_usr_ids)
1545    {
1546        global $DIC;
1547
1548        $ilErr = $DIC['ilErr'];
1549        $ilDB = $DIC['ilDB'];
1550
1551        if (!is_array($a_usr_ids) or !count($a_usr_ids)) {
1552            $ilErr->setMessage('');
1553            $ilErr->appendMessage($this->lng->txt("no_usr_ids_given"));
1554
1555            return false;
1556        }
1557        $query = "DELETE FROM il_subscribers " .
1558            "WHERE " . $ilDB->in('usr_id', (array) $a_usr_ids, false, 'integer') . " " .
1559            "AND obj_id = " . $ilDB->quote($this->obj_id, 'integer');
1560        $res = $ilDB->query($query);
1561        return true;
1562    }
1563
1564
1565    /**
1566     * check if is subscriber
1567     *
1568     * @access public
1569     */
1570    public function isSubscriber($a_usr_id)
1571    {
1572        global $DIC;
1573
1574        $ilDB = $DIC['ilDB'];
1575
1576        $query = "SELECT * FROM il_subscribers " .
1577            "WHERE usr_id = " . $ilDB->quote($a_usr_id, 'integer') . " " .
1578            "AND obj_id = " . $ilDB->quote($this->obj_id, 'integer') . "";
1579
1580        $res = $ilDB->query($query);
1581        while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1582            return true;
1583        }
1584        return false;
1585    }
1586
1587    /**
1588     * check if user is subscriber
1589     *
1590     * @access public
1591     * @static
1592     */
1593    public static function _isSubscriber($a_obj_id, $a_usr_id)
1594    {
1595        global $DIC;
1596
1597        $ilDB = $DIC['ilDB'];
1598
1599        $query = "SELECT * FROM il_subscribers " .
1600            "WHERE usr_id = " . $ilDB->quote($a_usr_id, 'integer') . " " .
1601            "AND obj_id = " . $ilDB->quote($a_obj_id, 'integer') . "";
1602
1603        $res = $ilDB->query($query);
1604        while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1605            return true;
1606        }
1607        return false;
1608    }
1609
1610    /**
1611     * read subscribers
1612     *
1613     * @access protected
1614     */
1615    protected function readSubscribers()
1616    {
1617        global $DIC;
1618
1619        $ilDB = $DIC['ilDB'];
1620
1621        $this->subscribers = array();
1622
1623        $query = "SELECT usr_id FROM il_subscribers " .
1624            "WHERE obj_id = " . $ilDB->quote($this->obj_id, 'integer') . " " .
1625            "ORDER BY sub_time ";
1626
1627        $res = $this->ilDB->query($query);
1628        while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1629            // DELETE SUBSCRIPTION IF USER HAS BEEN DELETED
1630            if (!ilObjectFactory::getInstanceByObjId($row->usr_id, false)) {
1631                $this->deleteSubscriber($row->usr_id);
1632            }
1633            $this->subscribers[] = $row->usr_id;
1634        }
1635        return true;
1636    }
1637
1638    /**
1639     * read subscribers
1640     *
1641     * @access protected
1642     */
1643    protected function readSubscriberData($a_usr_id)
1644    {
1645        global $DIC;
1646
1647        $ilDB = $DIC['ilDB'];
1648
1649        $query = "SELECT * FROM il_subscribers " .
1650            "WHERE obj_id = " . $ilDB->quote($this->obj_id, 'integer') . " " .
1651            "AND usr_id = " . $ilDB->quote($a_usr_id, 'integer') . "";
1652
1653        $res = $this->ilDB->query($query);
1654        while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1655            $data["time"] = $row->sub_time;
1656            $data["usr_id"] = $row->usr_id;
1657            $data['subject'] = $row->subject;
1658        }
1659        return $data ? $data : array();
1660    }
1661
1662    public static function lookupSubscribersData($a_obj_id)
1663    {
1664        global $DIC;
1665
1666        $ilDB = $DIC['ilDB'];
1667
1668        $query = 'SELECT * FROM il_subscribers ' .
1669            'WHERE obj_id = ' . $ilDB->quote($a_obj_id, 'integer');
1670        $res = $ilDB->query($query);
1671
1672        $data = array();
1673        while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1674            $data[$row->usr_id]['time'] = $row->sub_time;
1675            $data[$row->usr_id]['usr_id'] = $row->usr_id;
1676            $data[$row->usr_id]['subject'] = $row->subject;
1677        }
1678        return $data;
1679    }
1680
1681    /**
1682     * Get all support contacts for a user
1683     *
1684     * @param int $a_usr_id usr_id
1685     * @param string $a_type crs or grp
1686     * @return array array of contacts (keys are usr_id and obj_id)
1687     */
1688    public static function _getAllSupportContactsOfUser($a_usr_id, $a_type)
1689    {
1690        global $DIC;
1691
1692        $ilDB = $DIC['ilDB'];
1693
1694        // todo: join the two queries or alternatively reuse _getMembershipByType
1695        // for the first part
1696
1697        // this will also dismiss local roles!
1698        $j2 = "JOIN object_data obd2 ON (ua.rol_id = obd2.obj_id) ";
1699        $a2 = "AND obd2.title LIKE 'il_" . $a_type . "_mem%' ";
1700
1701        // #14290 - no role folder anymore
1702        $query = "SELECT DISTINCT obd.obj_id,obr.ref_id FROM rbac_ua ua " .
1703            "JOIN rbac_fa fa ON ua.rol_id = fa.rol_id " .
1704            "JOIN object_reference obr ON fa.parent = obr.ref_id " .
1705            "JOIN object_data obd ON obr.obj_id = obd.obj_id " .
1706            $j2 .
1707            "WHERE obd.type = " . $ilDB->quote($a_type, 'text') . " " .
1708            "AND fa.assign = 'y' " .
1709            "AND ua.usr_id = " . $ilDB->quote($a_usr_id, 'integer') . " " .
1710            $a2;
1711
1712        $res = $ilDB->query($query);
1713        $obj_ids = array();
1714        while ($row = $ilDB->fetchObject($res)) {
1715            $obj_ids[] = $row->obj_id;
1716        }
1717
1718        $set = $ilDB->query("SELECT obj_id, usr_id FROM obj_members " .
1719            " WHERE " . $ilDB->in("obj_id", $obj_ids, false, "integer") .
1720            " AND contact = " . $ilDB->quote(1, "integer"));
1721        $res = array();
1722        while ($rec = $ilDB->fetchAssoc($set)) {
1723            $res[] = $rec;
1724        }
1725
1726        return $res;
1727    }
1728
1729    /**
1730     * Set role order position
1731     * @param  int $a_user_id
1732     * @return string
1733     */
1734    public function setRoleOrderPosition($a_user_id)
1735    {
1736        $counter = 0;
1737        $sortable_assignments = '9999999999';
1738        foreach ($this->roles_sorted as $role_id => $trash) {
1739            if (in_array($a_user_id, (array) $this->role_assignments[$role_id])) {
1740                $sortable_assignments = substr_replace($sortable_assignments, '1', $counter, 1);
1741            }
1742            ++$counter;
1743        }
1744        return $sortable_assignments;
1745    }
1746}
1747