ILIAS  trunk Revision v11.0_alpha-1713-gd8962da2f67
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilParticipant.php
Go to the documentation of this file.
1 <?php
18 declare(strict_types=1);
19 
26 abstract class ilParticipant
27 {
28  protected const MEMBERSHIP_ADMIN = 1;
29  protected const MEMBERSHIP_TUTOR = 2;
30  protected const MEMBERSHIP_MEMBER = 3;
31 
32  private int $obj_id = 0;
33  private int $usr_id = 0;
34  protected string $type = '';
35  private int $ref_id = 0;
36 
37  private string $component = '';
38 
39  private array $roles = [];
40  private array $role_data = [];
41  private bool $participants = false;
42  private bool $admins = false;
43  private bool $tutors = false;
44  private bool $members = false;
45 
46  private ?int $numMembers = null;
47  private array $member_roles = [];
48  private array $participants_status = array();
49 
51  protected ilDBInterface $db;
56 
57  protected function __construct(string $a_component_name, int $a_obj_id, int $a_usr_id)
58  {
59  global $DIC;
60 
61  $this->obj_id = $a_obj_id;
62  $this->usr_id = $a_usr_id;
63  $this->type = ilObject::_lookupType($a_obj_id);
64  $ref_ids = ilObject::_getAllReferences($this->obj_id);
65  $this->ref_id = current($ref_ids);
66  $this->component = $a_component_name;
67 
68  $this->recommended_content_manager = new ilRecommendedContentManager();
69  $this->db = $DIC->database();
70  $this->rbacReview = $DIC->rbac()->review();
71  $this->rbacAdmin = $DIC->rbac()->admin();
72  $this->objectDataCache = $DIC['ilObjDataCache'];
73  $this->eventHandler = $DIC->event();
74 
75  $this->readParticipant();
76  $this->readParticipantStatus();
77  }
78 
79  public static function updateMemberRoles(int $a_obj_id, int $a_usr_id, int $a_role_id, int $a_status): void
80  {
81  global $DIC;
82 
83  $ilDB = $DIC->database();
84 
85  $a_membership_role_type = self::getMembershipRoleType($a_role_id);
86  switch ($a_membership_role_type) {
87  case self::MEMBERSHIP_ADMIN:
88  $update_fields = array('admin' => array('integer', $a_status ? 1 : 0));
89  $update_string = ('admin = ' . $ilDB->quote($a_status ? 1 : 0, 'integer'));
90  break;
91 
92  case self::MEMBERSHIP_TUTOR:
93  $update_fields = array('tutor' => array('integer', $a_status ? 1 : 0));
94  $update_string = ('tutor = ' . $ilDB->quote($a_status ? 1 : 0, 'integer'));
95  break;
96 
97  case self::MEMBERSHIP_MEMBER:
98  default:
99  $current_status = self::lookupStatusByMembershipRoleType($a_obj_id, $a_usr_id, $a_membership_role_type);
100 
101  if ($a_status) {
102  $new_status = $current_status + 1;
103  }
104  if (!$a_status) {
105  $new_status = $current_status - 1;
106  if ($new_status < 0) {
107  $new_status = 0;
108  }
109  }
110 
111  $update_fields = array('member' => array('integer', $new_status));
112  $update_string = ('member = ' . $ilDB->quote($new_status, 'integer'));
113  break;
114  }
115 
116  $query = 'SELECT count(*) num FROM obj_members ' .
117  'WHERE obj_id = ' . $ilDB->quote($a_obj_id, 'integer') . ' ' .
118  'AND usr_id = ' . $ilDB->quote($a_usr_id, 'integer');
119  $res = $ilDB->query($query);
120 
121  $found = false;
122  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
123  if ($row->num) {
124  $found = true;
125  }
126  }
127  if (!$found) {
128  $ilDB->replace(
129  'obj_members',
130  array(
131  'obj_id' => array('integer', $a_obj_id),
132  'usr_id' => array('integer', $a_usr_id)
133  ),
134  $update_fields
135  );
136  } else {
137  $query = 'UPDATE obj_members SET ' .
138  $update_string . ' ' .
139  'WHERE obj_id = ' . $ilDB->quote($a_obj_id, 'integer') . ' ' .
140  'AND usr_id = ' . $ilDB->quote($a_usr_id, 'integer');
141 
142  $ilDB->manipulate($query);
143  }
144 
145  $query = 'DELETE from obj_members ' .
146  'WHERE obj_id = ' . $ilDB->quote($a_obj_id, 'integer') . ' ' .
147  'AND usr_id = ' . $ilDB->quote($a_usr_id, 'integer') . ' ' .
148  'AND admin = ' . $ilDB->quote(0, 'integer') . ' ' .
149  'AND tutor = ' . $ilDB->quote(0, 'integer') . ' ' .
150  'AND member = ' . $ilDB->quote(0, 'integer');
151  $ilDB->manipulate($query);
152  }
153 
154  public static function getMembershipRoleType(int $a_role_id): int
155  {
156  $title = ilObject::_lookupTitle($a_role_id);
157  switch (substr($title, 0, 8)) {
158  case 'il_crs_a':
159  case 'il_grp_a':
160  return self::MEMBERSHIP_ADMIN;
161 
162  case 'il_crs_t':
163  return self::MEMBERSHIP_TUTOR;
164 
165  case 'il_crs_m':
166  default:
167  return self::MEMBERSHIP_MEMBER;
168  }
169  }
170 
171  public static function lookupStatusByMembershipRoleType(
172  int $a_obj_id,
173  int $a_usr_id,
174  int $a_membership_role_type
175  ): int {
176  global $DIC;
177 
178  $ilDB = $DIC->database();
179  $query = 'SELECT * FROM obj_members ' .
180  'WHERE obj_id = ' . $ilDB->quote($a_obj_id, 'integer') . ' ' .
181  'AND usr_id = ' . $ilDB->quote($a_usr_id, ilDBConstants::T_INTEGER) . ' ';
182  $res = $ilDB->query($query);
183  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
184  switch ($a_membership_role_type) {
185  case self::MEMBERSHIP_ADMIN:
186  return (int) $row->admin;
187 
188  case self::MEMBERSHIP_TUTOR:
189  return (int) $row->tutor;
190 
191  case self::MEMBERSHIP_MEMBER:
192  return (int) $row->member;
193  }
194  }
195  return 0;
196  }
197 
202  protected function getComponent(): string
203  {
204  return $this->component;
205  }
206 
207  public function getUserId(): int
208  {
209  return $this->usr_id;
210  }
211 
212  public function isBlocked(): bool
213  {
214  return (bool) ($this->participants_status[$this->getUserId()]['blocked'] ?? false);
215  }
216 
220  public function isContact(): bool
221  {
222  return (bool) ($this->participants_status[$this->getUserId()]['contact'] ?? false);
223  }
224 
225  public function isAssigned(): bool
226  {
227  return $this->participants;
228  }
229 
230  public function isMember(): bool
231  {
232  return $this->members;
233  }
234 
235  public function isAdmin(): bool
236  {
237  return $this->admins;
238  }
239 
240  public function isTutor(): bool
241  {
242  return $this->tutors;
243  }
244 
245  public function isParticipant(): bool
246  {
247  return $this->participants;
248  }
249 
250  public function getNumberOfMembers(): int
251  {
252  if ($this->numMembers === null) {
253  $this->numMembers = $this->rbacReview->getNumberOfAssignedUsers($this->member_roles);
254  }
255  return $this->numMembers;
256  }
257 
258  protected function readParticipant(): void
259  {
260  $this->roles = $this->rbacReview->getRolesOfRoleFolder($this->ref_id, false);
261  $this->member_roles = [];
262  foreach ($this->roles as $role_id) {
263  $title = $this->objectDataCache->lookupTitle($role_id);
264  switch (substr($title, 0, 8)) {
265  case 'il_crs_m':
266  $this->member_roles[] = $role_id;
267  $this->role_data[ilParticipants::IL_CRS_MEMBER] = $role_id;
268  if ($this->rbacReview->isAssigned($this->getUserId(), $role_id)) {
269  $this->participants = true;
270  $this->members = true;
271  }
272  break;
273 
274  case 'il_crs_a':
275  $this->role_data[ilParticipants::IL_CRS_ADMIN] = $role_id;
276  if ($this->rbacReview->isAssigned($this->getUserId(), $role_id)) {
277  $this->participants = true;
278  $this->admins = true;
279  }
280  break;
281 
282  case 'il_crs_t':
283  $this->role_data[ilParticipants::IL_CRS_TUTOR] = $role_id;
284  if ($this->rbacReview->isAssigned($this->getUserId(), $role_id)) {
285  $this->participants = true;
286  $this->tutors = true;
287  }
288  break;
289 
290  case 'il_grp_a':
291  $this->role_data[ilParticipants::IL_GRP_ADMIN] = $role_id;
292  if ($this->rbacReview->isAssigned($this->getUserId(), $role_id)) {
293  $this->participants = true;
294  $this->admins = true;
295  }
296  break;
297 
298  case 'il_grp_m':
299  $this->member_roles[] = $role_id;
300  $this->role_data[ilParticipants::IL_GRP_MEMBER] = $role_id;
301  if ($this->rbacReview->isAssigned($this->getUserId(), $role_id)) {
302  $this->participants = true;
303  $this->members = true;
304  }
305  break;
306 
307  default:
308 
309  $this->member_roles[] = $role_id;
310  if ($this->rbacReview->isAssigned($this->getUserId(), $role_id)) {
311  $this->participants = true;
312  $this->members = true;
313  }
314  break;
315  }
316  }
317  }
318 
319  protected function readParticipantStatus(): void
320  {
321  $query = "SELECT * FROM obj_members " .
322  "WHERE obj_id = " . $this->db->quote($this->obj_id, 'integer') . " " .
323  'AND usr_id = ' . $this->db->quote($this->getUserId(), 'integer');
324 
325  $res = $this->db->query($query);
326  $this->participants_status = array();
327  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
328  $this->participants_status[$this->getUserId()]['blocked'] = (bool) $row->blocked;
329  $this->participants_status[$this->getUserId()]['notification'] = (bool) $row->notification;
330  $this->participants_status[$this->getUserId()]['passed'] = (bool) $row->passed;
331  $this->participants_status[$this->getUserId()]['contact'] = (bool) $row->contact;
332  }
333  }
334 
335  public function add(int $a_usr_id, int $a_role): bool
336  {
337  if ($this->rbacReview->isAssignedToAtLeastOneGivenRole($a_usr_id, $this->roles)) {
338  return false;
339  }
340 
341  switch ($a_role) {
344  $this->admins = true;
345  break;
346 
348  $this->tutors = true;
349  break;
350 
353  $this->members = true;
354  break;
355  }
356 
357  $this->rbacAdmin->assignUser($this->role_data[$a_role], $a_usr_id);
358  $this->addRecommendation($a_usr_id);
359 
360  // Delete subscription request
361  $this->deleteSubscriber($a_usr_id);
362 
363  ilWaitingList::deleteUserEntry($a_usr_id, $this->obj_id);
364 
365  $this->eventHandler->raise(
366  $this->getComponent(),
367  "addParticipant",
368  array(
369  'obj_id' => $this->obj_id,
370  'usr_id' => $a_usr_id,
371  'role_id' => $a_role
372  )
373  );
374  return true;
375  }
376 
377  public function delete(int $a_usr_id): void
378  {
379  $this->recommended_content_manager->removeObjectRecommendation($a_usr_id, $this->ref_id);
380  foreach ($this->roles as $role_id) {
381  $this->rbacAdmin->deassignUser($role_id, $a_usr_id);
382  }
383 
384  $query = "DELETE FROM obj_members " .
385  "WHERE usr_id = " . $this->db->quote($a_usr_id, 'integer') . " " .
386  "AND obj_id = " . $this->db->quote($this->obj_id, 'integer');
387  $res = $this->db->manipulate($query);
388 
389  $this->eventHandler->raise(
390  $this->getComponent(),
391  "deleteParticipant",
392  array(
393  'obj_id' => $this->obj_id,
394  'usr_id' => $a_usr_id
395  )
396  );
397  }
398 
399  public function deleteSubscriber(int $a_usr_id): void
400  {
401  $query = "DELETE FROM il_subscribers " .
402  "WHERE usr_id = " . $this->db->quote($a_usr_id, 'integer') . " " .
403  "AND obj_id = " . $this->db->quote($this->obj_id, 'integer') . " ";
404  $res = $this->db->manipulate($query);
405  }
406 
407  public function addRecommendation($a_usr_id): void
408  {
409  // deactivated for now, see discussion at
410  // https://docu.ilias.de/goto_docu_wiki_wpage_5620_1357.html
411  //$this->recommended_content_manager->addObjectRecommendation($a_usr_id, $this->ref_id);
412  }
413 
414  public function updateContact(int $a_usr_id, bool $a_contact): void
415  {
416  $this->db->manipulate(
417  'UPDATE obj_members SET ' .
418  'contact = ' . $this->db->quote($a_contact, 'integer') . ' ' .
419  'WHERE obj_id = ' . $this->db->quote($this->obj_id, 'integer') . ' ' .
420  'AND usr_id = ' . $this->db->quote($a_usr_id, 'integer')
421  );
422  $this->participants_status[$a_usr_id]['contact'] = $a_contact;
423  }
424 
425  public function updateNotification(int $a_usr_id, bool $a_notification): void
426  {
427  $this->participants_status[$a_usr_id]['notification'] = $a_notification;
428 
429  $query = "SELECT * FROM obj_members " .
430  "WHERE obj_id = " . $this->db->quote($this->obj_id, 'integer') . " " .
431  "AND usr_id = " . $this->db->quote($a_usr_id, 'integer');
432  $res = $this->db->query($query);
433  if ($res->numRows()) {
434  $query = "UPDATE obj_members SET " .
435  "notification = " . $this->db->quote((int) $a_notification, 'integer') . " " .
436  "WHERE obj_id = " . $this->db->quote($this->obj_id, 'integer') . " " .
437  "AND usr_id = " . $this->db->quote($a_usr_id, 'integer');
438  } else {
439  $query = "INSERT INTO obj_members (notification,obj_id,usr_id,passed,blocked) " .
440  "VALUES ( " .
441  $this->db->quote((int) $a_notification, 'integer') . ", " .
442  $this->db->quote($this->obj_id, 'integer') . ", " .
443  $this->db->quote($a_usr_id, 'integer') . ", " .
444  $this->db->quote(0, 'integer') . ", " .
445  $this->db->quote(0, 'integer') .
446  ") ON DUPLICATE KEY UPDATE notification = VALUES(notification)";
447  }
448  $this->db->manipulate($query);
449  }
450 
451  public function checkLastAdmin(array $a_usr_ids): bool
452  {
453  $admin_role_id =
454  $this->type === 'crs' ?
455  $this->role_data[ilParticipants::IL_CRS_ADMIN] :
456  $this->role_data[ilParticipants::IL_GRP_ADMIN];
457 
458  $query = "
459  SELECT COUNT(rolesusers.usr_id) cnt
460 
461  FROM object_data rdata
462 
463  LEFT JOIN rbac_ua rolesusers
464  ON rolesusers.rol_id = rdata.obj_id
465 
466  WHERE rdata.obj_id = %s
467  ";
468 
469  $query .= ' AND ' . $this->db->in('rolesusers.usr_id', $a_usr_ids, true, 'integer');
470  $res = $this->db->queryF($query, array('integer'), array($admin_role_id));
471 
472  $data = $this->db->fetchAssoc($res);
473  return $data['cnt'] > 0;
474  }
475 }
__construct(string $a_component_name, int $a_obj_id, int $a_usr_id)
$res
Definition: ltiservices.php:66
Global event handler.
static getMembershipRoleType(int $a_role_id)
updateContact(int $a_usr_id, bool $a_contact)
isContact()
Check if user is contact for current object.
static _getAllReferences(int $id)
get all reference ids for object ID
ilRbacReview $rbacReview
getComponent()
Get component name Used for event handling.
ilRbacAdmin $rbacAdmin
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static updateMemberRoles(int $a_obj_id, int $a_usr_id, int $a_role_id, int $a_status)
addRecommendation($a_usr_id)
updateNotification(int $a_usr_id, bool $a_notification)
add(int $a_usr_id, int $a_role)
static _lookupTitle(int $obj_id)
static lookupStatusByMembershipRoleType(int $a_obj_id, int $a_usr_id, int $a_membership_role_type)
global $DIC
Definition: shib_login.php:22
Base class for course and group participant.
static deleteUserEntry(int $a_usr_id, int $a_obj_id)
ilRecommendedContentManager $recommended_content_manager
deleteSubscriber(int $a_usr_id)
ilObjectDataCache $objectDataCache
ilAppEventHandler $eventHandler
checkLastAdmin(array $a_usr_ids)
Class ilRbacAdmin Core functions for role based access control.
static _lookupType(int $id, bool $reference=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ilDBInterface $db