ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilObjGroup.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
32{
33 public const CAL_REG_START = 1;
34 public const CAL_REG_END = 2;
35 public const CAL_START = 3;
36 public const CAL_END = 4;
37
38 public const GRP_MEMBER = 1;
39 public const GRP_ADMIN = 2;
40
41 public const ERR_MISSING_TITLE = 'msg_no_title';
42 public const ERR_MISSING_GROUP_TYPE = 'grp_missing_grp_type';
43 public const ERR_MISSING_PASSWORD = 'grp_missing_password';
44 public const ERR_WRONG_MAX_MEMBERS = 'grp_wrong_max_members';
45 public const ERR_WRONG_REG_TIME_LIMIT = 'grp_wrong_reg_time_limit';
46 public const ERR_MISSING_MIN_MAX_MEMBERS = 'grp_wrong_min_max_members';
47 public const ERR_WRONG_MIN_MAX_MEMBERS = 'grp_max_and_min_members_invalid';
48 public const ERR_WRONG_REGISTRATION_LIMITED = 'grp_err_registration_limited';
49
50 public const MAIL_ALLOWED_ALL = 1;
51 public const MAIL_ALLOWED_TUTORS = 2;
52
55
56 private string $information = '';
57 private int $group_status = 0;
60 private bool $reg_unlimited = true;
61 private ?ilDateTime $reg_start = null;
62 private ?ilDateTime $reg_end = null;
63 private string $reg_password = '';
64 private bool $reg_membership_limitation = false;
65 private int $reg_min_members = 0;
66 private int $reg_max_members = 0;
67 private bool $waiting_list = false;
68 private bool $auto_fill_from_waiting = false;
69 private ?ilDate $leave_end = null;
70 private bool $show_members = true;
71 private bool $session_limit = false;
72 private int $session_prev = -1;
73 private int $session_next = -1;
74 private bool $start_time_indication = false;
75 private ?ilDateTime $grp_start = null;
76 private ?ilDateTime $grp_end = null;
77 private bool $auto_notification = true;
78 private string $latitude = '';
79 private string $longitude = '';
80 private int $locationzoom = 0;
81 private bool $enablemap = false;
82 private string $reg_access_code = '';
83 private bool $reg_access_code_enabled = false;
86
88
89
91
93
95
96 private string $message = '';
97
98 private array $local_roles = [];
99
100
104 public function __construct(int $a_id = 0, bool $a_call_by_reference = true)
105 {
106 global $DIC;
107
108 $tree = $DIC['tree'];
109
110 $this->tree = &$tree;
111
112 $this->type = "grp";
113 parent::__construct($a_id, $a_call_by_reference);
114
115 $this->logger = $DIC->logger()->grp();
116 }
117
118 public static function lookupGroupTye(int $a_id): int
119 {
120 global $DIC;
121
122 $ilDB = $DIC->database();
123
124 $query = "SELECT grp_type FROM grp_settings " .
125 "WHERE obj_id = " . $ilDB->quote($a_id, 'integer');
126 $res = $ilDB->query($query);
127 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
128 return (int) $row->grp_type;
129 }
131 }
132
133 public function setInformation(string $a_information): void
134 {
135 $this->information = $a_information;
136 }
137
138 public function getInformation(): string
139 {
140 return $this->information;
141 }
142
143 public function setGroupType(int $a_type): void
144 {
145 $this->group_type = $a_type;
146 }
147
148 public function getGroupType(): int
149 {
150 return $this->group_type;
151 }
152
153 public function setRegistrationType(int $a_type): void
154 {
155 $this->reg_type = $a_type;
156 }
157
158 public function getRegistrationType(): int
159 {
160 return $this->reg_type;
161 }
162
163 public function isRegistrationEnabled(): bool
164 {
166 }
167
168 public function enableUnlimitedRegistration(bool $a_status): void
169 {
170 $this->reg_unlimited = $a_status;
171 }
172
173 public function isRegistrationUnlimited(): bool
174 {
176 }
177
178 public function setRegistrationStart(?ilDateTime $a_start): void
179 {
180 $this->reg_start = $a_start;
181 }
182
184 {
185 return $this->reg_start;
186 }
187
188
189 public function setRegistrationEnd(?ilDateTime $a_end): void
190 {
191 $this->reg_end = $a_end;
192 }
193
194 public function getRegistrationEnd(): ?ilDateTime
195 {
196 return $this->reg_end;
197 }
198
199 public function setPassword(string $a_pass): void
200 {
201 $this->reg_password = $a_pass;
202 }
203
204 public function getPassword(): string
205 {
206 return $this->reg_password;
207 }
208
209 public function enableMembershipLimitation(bool $a_status): void
210 {
211 $this->reg_membership_limitation = $a_status;
212 }
213
214 public function isMembershipLimited(): bool
215 {
217 }
218
219 public function setMinMembers(int $a_max): void
220 {
221 $this->reg_min_members = $a_max;
222 }
223
224 public function getMinMembers(): int
225 {
227 }
228
229 public function setMaxMembers(int $a_max): void
230 {
231 $this->reg_max_members = $a_max;
232 }
233
234 public function getMaxMembers(): int
235 {
237 }
238
239 public function enableWaitingList(bool $a_status): void
240 {
241 $this->waiting_list = $a_status;
242 }
243
244 public function isWaitingListEnabled(): bool
245 {
246 return $this->waiting_list;
247 }
248
249 public function setWaitingListAutoFill(bool $a_value): void
250 {
251 $this->auto_fill_from_waiting = $a_value;
252 }
253
254 public function hasWaitingListAutoFill(): bool
255 {
257 }
258
259 public function setLatitude(string $a_latitude): void
260 {
261 $this->latitude = $a_latitude;
262 }
263
264 public function getLatitude(): string
265 {
266 return $this->latitude;
267 }
268
269 public function setLongitude(string $a_longitude): void
270 {
271 $this->longitude = $a_longitude;
272 }
273
274 public function getLongitude(): string
275 {
276 return $this->longitude;
277 }
278
279 public function setLocationZoom(int $a_locationzoom): void
280 {
281 $this->locationzoom = $a_locationzoom;
282 }
283
284 public function getLocationZoom(): int
285 {
286 return $this->locationzoom;
287 }
288
289 public function setEnableGroupMap(bool $a_enablemap): void
290 {
291 $this->enablemap = $a_enablemap;
292 }
293
294 public function getEnableMap(): bool
295 {
296 return $this->getEnableGroupMap();
297 }
298
299 public function getEnableGroupMap(): bool
300 {
301 return $this->enablemap;
302 }
303
304 public function getRegistrationAccessCode(): string
305 {
307 }
308
309 public function setRegistrationAccessCode(string $a_code): void
310 {
311 $this->reg_access_code = $a_code;
312 }
313
314 public function isRegistrationAccessCodeEnabled(): bool
315 {
317 }
318
319 public function enableRegistrationAccessCode(bool $a_status): void
320 {
321 $this->reg_access_code_enabled = $a_status;
322 }
323
324 public function setMailToMembersType(int $a_type): void
325 {
326 $this->mail_members = $a_type;
327 }
328
329 public function getMailToMembersType(): int
330 {
331 return $this->mail_members;
332 }
333
334 public function setCancellationEnd(?ilDate $a_value): void
335 {
336 $this->leave_end = $a_value;
337 }
338
339 public function getCancellationEnd(): ?ilDate
340 {
341 return $this->leave_end;
342 }
343
344 public function setShowMembers(bool $a_status): void
345 {
346 $this->show_members = $a_status;
347 }
348 public function getShowMembers(): bool
349 {
350 return $this->show_members;
351 }
352
353 public function setAutoNotification(bool $a_status): void
354 {
355 $this->auto_notification = $a_status;
356 }
357
358 public function getAutoNotification(): bool
359 {
361 }
362
363 public function setPeriod(?\ilDateTime $start = null, ?\ilDateTime $end = null): void
364 {
365 if (
366 ($start instanceof \ilDate && !$end instanceof ilDate) ||
367 ($end instanceof \ilDate && !$start instanceof ilDate)
368 ) {
369 throw new InvalidArgumentException('Different date types not supported.');
370 }
371
372 if ($start instanceof \ilDate) {
373 $this->toggleStartTimeIndication(false);
374 } else {
375 $this->toggleStartTimeIndication(true);
376 }
377 $this->setStart($start);
378 $this->setEnd($end);
379 }
380
381 protected function toggleStartTimeIndication(bool $time_indication): void
382 {
383 $this->start_time_indication = $time_indication;
384 }
385
386 public function getStartTimeIndication(): bool
387 {
389 }
390
391
392 protected function setStart(?ilDateTime $a_value = null): void
393 {
394 $this->grp_start = $a_value;
395 }
396
397 public function getStart(): ?\ilDateTime
398 {
399 return $this->grp_start;
400 }
401
402 protected function setEnd(?ilDateTime $a_value = null): void
403 {
404 $this->grp_end = $a_value;
405 }
406
407 public function getEnd(): ?\ilDateTime
408 {
409 return $this->grp_end;
410 }
411
412 public function enableSessionLimit(bool $a_status): void
413 {
414 $this->session_limit = $a_status;
415 }
416
417 public function isSessionLimitEnabled(): bool
418 {
420 }
421
422 public function setNumberOfPreviousSessions(int $a_num): void
423 {
424 $this->session_prev = $a_num;
425 }
426
428 {
429 return $this->session_prev;
430 }
431
432 public function setNumberOfNextSessions(int $a_num): void
433 {
434 $this->session_next = $a_num;
435 }
436
437 public function getNumberOfNextSessions(): int
438 {
439 return $this->session_next;
440 }
441
442
446 public function validate(): bool
447 {
448 if (!$this->getTitle()) {
449 $this->title = '';
450 $this->error->appendMessage($this->lng->txt(self::ERR_MISSING_TITLE));
451 }
453 $this->error->appendMessage($this->lng->txt(self::ERR_MISSING_PASSWORD));
454 }
455 if ($this->isMembershipLimited()) {
456 if ($this->getMinMembers() <= 0 && $this->getMaxMembers() <= 0) {
457 $this->error->appendMessage($this->lng->txt(self::ERR_MISSING_MIN_MAX_MEMBERS));
458 }
459 if ($this->getMaxMembers() <= 0 && $this->isWaitingListEnabled()) {
460 $this->error->appendMessage($this->lng->txt(self::ERR_WRONG_MAX_MEMBERS));
461 }
462 if ($this->getMaxMembers() > 0 && $this->getMinMembers() > $this->getMaxMembers()) {
463 $this->error->appendMessage($this->lng->txt(self::ERR_WRONG_MIN_MAX_MEMBERS));
464 }
465 }
466 if (
467 ($this->getRegistrationStart() && !$this->getRegistrationEnd()) ||
468 (!$this->getRegistrationStart() && $this->getRegistrationEnd()) ||
469 $this->getRegistrationEnd() <= $this->getRegistrationStart()
470 ) {
471 $this->error->appendMessage($this->lng->txt((self::ERR_WRONG_REGISTRATION_LIMITED)));
472 }
473 return strlen($this->error->getMessage()) == 0;
474 }
475
476
477
478
482 public function create(): int
483 {
484 if (!parent::create()) {
485 return 0;
486 }
487 $this->createMetaData();
488
489 $query = "INSERT INTO grp_settings (obj_id,information,grp_type,registration_type,registration_enabled," .
490 "registration_unlimited,registration_start,registration_end,registration_password,registration_mem_limit," .
491 "registration_max_members,waiting_list,latitude,longitude,location_zoom,enablemap,reg_ac_enabled,reg_ac,view_mode,mail_members_type," .
492 "leave_end,registration_min_members,auto_wait, grp_start, grp_end, auto_notification, session_limit, session_prev, session_next) " .
493 "VALUES(" .
494 $this->db->quote($this->getId(), 'integer') . ", " .
495 $this->db->quote($this->getInformation(), 'text') . ", " .
496 $this->db->quote($this->getGroupType(), 'integer') . ", " .
497 $this->db->quote($this->getRegistrationType(), 'integer') . ", " .
498 $this->db->quote(($this->isRegistrationEnabled() ? 1 : 0), 'integer') . ", " .
499 $this->db->quote(($this->isRegistrationUnlimited() ? 1 : 0), 'integer') . ", " .
500 $this->db->quote(($this->getRegistrationStart() && !$this->getRegistrationStart()->isNull()) ? $this->getRegistrationStart()->get(IL_CAL_DATETIME, '') : null, 'timestamp') . ", " .
501 $this->db->quote(($this->getRegistrationEnd() && !$this->getRegistrationEnd()->isNull()) ? $this->getRegistrationEnd()->get(IL_CAL_DATETIME, '') : null, 'timestamp') . ", " .
502 $this->db->quote($this->getPassword(), 'text') . ", " .
503 $this->db->quote((int) $this->isMembershipLimited(), 'integer') . ", " .
504 $this->db->quote($this->getMaxMembers(), 'integer') . ", " .
505 $this->db->quote($this->isWaitingListEnabled() ? 1 : 0, 'integer') . ", " .
506 $this->db->quote($this->getLatitude(), 'text') . ", " .
507 $this->db->quote($this->getLongitude(), 'text') . ", " .
508 $this->db->quote($this->getLocationZoom(), 'integer') . ", " .
509 $this->db->quote((int) $this->getEnableGroupMap(), 'integer') . ", " .
510 $this->db->quote($this->isRegistrationAccessCodeEnabled(), 'integer') . ', ' .
511 $this->db->quote($this->getRegistrationAccessCode(), 'text') . ', ' .
512 $this->db->quote($this->view_mode, 'integer') . ', ' .
513 $this->db->quote($this->getMailToMembersType(), 'integer') . ', ' .
514 $this->db->quote(($this->getCancellationEnd() && !$this->getCancellationEnd()->isNull()) ? $this->getCancellationEnd()->get(IL_CAL_UNIX) : null, 'integer') . ', ' .
515 $this->db->quote($this->getMinMembers(), 'integer') . ', ' .
516 $this->db->quote($this->hasWaitingListAutoFill(), 'integer') . ', ' .
517 $this->db->quote($this->getStart() instanceof ilDate ? $this->getStart()->get(IL_CAL_UNIX) : null, 'integer') . ', ' .
518 $this->db->quote($this->getEnd() instanceof ilDate ? $this->getEnd()->get(IL_CAL_UNIX) : null, 'integer') . ', ' .
519 $this->db->quote($this->getAutoNotification(), \ilDBConstants::T_INTEGER) . ', ' .
520 $this->db->quote($this->isSessionLimitEnabled(), ilDBConstants::T_INTEGER) . ', ' .
521 $this->db->quote($this->getNumberOfPreviousSessions(), ilDBConstants::T_INTEGER) . ', ' .
522 $this->db->quote($this->getNumberOfNextSessions(), ilDBConstants::T_INTEGER) .
523 ')';
524 $res = $this->db->manipulate($query);
525
526 $this->app_event_handler->raise(
527 'components/ILIAS/Group',
528 'create',
529 array('object' => $this,
530 'obj_id' => $this->getId(),
531 'appointments' => $this->prepareAppointments('create'))
532 );
533 return $this->getId();
534 }
535
539 public function update(): bool
540 {
541 if (!parent::update()) {
542 return false;
543 }
544
545 $this->updateMetaData();
546
547 $query = "UPDATE grp_settings " .
548 "SET information = " . $this->db->quote($this->getInformation(), 'text') . ", " .
549 "grp_type = " . $this->db->quote($this->getGroupType(), 'integer') . ", " .
550 "registration_type = " . $this->db->quote($this->getRegistrationType(), 'integer') . ", " .
551 "registration_enabled = " . $this->db->quote($this->isRegistrationEnabled() ? 1 : 0, 'integer') . ", " .
552 "registration_unlimited = " . $this->db->quote($this->isRegistrationUnlimited() ? 1 : 0, 'integer') . ", " .
553 "registration_start = " . $this->db->quote(($this->getRegistrationStart() && !$this->getRegistrationStart()->isNull()) ? $this->getRegistrationStart()->get(IL_CAL_DATETIME, '') : null, 'timestamp') . ", " .
554 "registration_end = " . $this->db->quote(($this->getRegistrationEnd() && !$this->getRegistrationEnd()->isNull()) ? $this->getRegistrationEnd()->get(IL_CAL_DATETIME, '') : null, 'timestamp') . ", " .
555 "registration_password = " . $this->db->quote($this->getPassword(), 'text') . ", " .
556// "registration_membership_limited = ".$this->db->quote((int) $this->isMembershipLimited() ,'integer').", ".
557 "registration_mem_limit = " . $this->db->quote((int) $this->isMembershipLimited(), 'integer') . ", " .
558 "registration_max_members = " . $this->db->quote($this->getMaxMembers(), 'integer') . ", " .
559 "waiting_list = " . $this->db->quote($this->isWaitingListEnabled() ? 1 : 0, 'integer') . ", " .
560 "latitude = " . $this->db->quote($this->getLatitude(), 'text') . ", " .
561 "longitude = " . $this->db->quote($this->getLongitude(), 'text') . ", " .
562 "location_zoom = " . $this->db->quote($this->getLocationZoom(), 'integer') . ", " .
563 "enablemap = " . $this->db->quote((int) $this->getEnableGroupMap(), 'integer') . ", " .
564 'reg_ac_enabled = ' . $this->db->quote($this->isRegistrationAccessCodeEnabled(), 'integer') . ', ' .
565 'reg_ac = ' . $this->db->quote($this->getRegistrationAccessCode(), 'text') . ', ' .
566 'view_mode = ' . $this->db->quote($this->view_mode, 'integer') . ', ' .
567 'mail_members_type = ' . $this->db->quote($this->getMailToMembersType(), 'integer') . ', ' .
568 'leave_end = ' . $this->db->quote(($this->getCancellationEnd() && !$this->getCancellationEnd()->isNull()) ? $this->getCancellationEnd()->get(IL_CAL_UNIX) : null, 'integer') . ', ' .
569 "registration_min_members = " . $this->db->quote($this->getMinMembers(), 'integer') . ", " .
570 "auto_wait = " . $this->db->quote($this->hasWaitingListAutoFill(), 'integer') . ", " .
571 "show_members = " . $this->db->quote((int) $this->getShowMembers(), 'integer') . ", " .
572 'period_start = ' . $this->db->quote(\ilCalendarUtil::convertDateToUtcDBTimestamp($this->getStart()), \ilDBConstants::T_TIMESTAMP) . ', ' .
573 'period_end = ' . $this->db->quote(\ilCalendarUtil::convertDateToUtcDBTimestamp($this->getEnd()), \ilDBConstants::T_TIMESTAMP) . ', ' .
574 'period_time_indication = ' . $this->db->quote($this->getStartTimeIndication() ? 1 : 0, \ilDBConstants::T_INTEGER) . ', ' .
575 'auto_notification = ' . $this->db->quote($this->getAutoNotification(), \ilDBConstants::T_INTEGER) . ', ' .
576 'session_limit = ' . $this->db->quote($this->isSessionLimitEnabled(), ilDBConstants::T_INTEGER) . ', ' .
577 'session_prev = ' . $this->db->quote($this->getNumberOfPreviousSessions(), ilDBConstants::T_INTEGER) . ', ' .
578 'session_next = ' . $this->db->quote($this->getNumberOfNextSessions(), ilDBConstants::T_INTEGER) . ' ' .
579 "WHERE obj_id = " . $this->db->quote($this->getId(), 'integer');
580 $res = $this->db->manipulate($query);
581
582 $this->app_event_handler->raise(
583 'components/ILIAS/Group',
584 'update',
585 array('object' => $this,
586 'obj_id' => $this->getId(),
587 'appointments' => $this->prepareAppointments('update'))
588 );
589 return true;
590 }
591
595 public function delete(): bool
596 {
597 // always call parent delete function first!!
598 if (!parent::delete()) {
599 return false;
600 }
601
602 $this->deleteMetaData();
603
604 $query = "DELETE FROM grp_settings " .
605 "WHERE obj_id = " . $this->db->quote($this->getId(), 'integer');
606 $res = $this->db->manipulate($query);
607
609
610 $this->app_event_handler->raise(
611 'components/ILIAS/Group',
612 'delete',
613 array('object' => $this,
614 'obj_id' => $this->getId(),
615 'appointments' => $this->prepareAppointments('delete'))
616 );
617 return true;
618 }
619
620
624 public function read(): void
625 {
626 parent::read();
627
628 $query = "SELECT * FROM grp_settings " .
629 "WHERE obj_id = " . $this->db->quote($this->getId(), 'integer');
630
631 $res = $this->db->query($query);
632 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
633 $this->setInformation((string) $row->information);
634 $this->setGroupType((int) $row->grp_type);
635 $this->setRegistrationType((int) $row->registration_type);
636 $this->enableUnlimitedRegistration((bool) $row->registration_unlimited);
637 $this->setRegistrationStart(new ilDateTime($row->registration_start, IL_CAL_DATETIME));
638 $this->setRegistrationEnd(new ilDateTime($row->registration_end, IL_CAL_DATETIME));
639 $this->setPassword((string) $row->registration_password);
640 $this->enableMembershipLimitation((bool) $row->registration_mem_limit);
641 $this->setMaxMembers((int) $row->registration_max_members);
642 $this->enableWaitingList((bool) $row->waiting_list);
643 $this->setLatitude((string) $row->latitude);
644 $this->setLongitude((string) $row->longitude);
645 $this->setLocationZoom((int) $row->location_zoom);
646 $this->setEnableGroupMap((bool) $row->enablemap);
647 $this->enableRegistrationAccessCode((bool) $row->reg_ac_enabled);
648 $this->setRegistrationAccessCode((string) $row->reg_ac);
649 $this->setViewMode((int) $row->view_mode);
650 $this->setMailToMembersType((int) $row->mail_members_type);
651 $this->setCancellationEnd($row->leave_end ? new ilDate((int) $row->leave_end, IL_CAL_UNIX) : null);
652 $this->setMinMembers((int) $row->registration_min_members);
653 $this->setWaitingListAutoFill((bool) $row->auto_wait);
654 $this->setShowMembers((bool) $row->show_members);
655 $this->setAutoNotification((bool) $row->auto_notification);
656 if ($row->period_time_indication) {
657 $this->setPeriod(
658 new \ilDateTime($row->period_start, IL_CAL_DATETIME, \ilTimeZone::UTC),
659 new \ilDateTime($row->period_end, IL_CAL_DATETIME, \ilTimeZone::UTC)
660 );
661 } elseif (!is_null($row->period_start) && !is_null($row->period_end)) {
662 $this->setPeriod(
663 new \ilDate($row->period_start, IL_CAL_DATE),
664 new \ilDate($row->period_end, IL_CAL_DATE)
665 );
666 }
667 $this->toggleStartTimeIndication((bool) $row->period_time_indication);
668 $this->enableSessionLimit((bool) $row->session_limit);
669 $this->setNumberOfPreviousSessions((int) $row->session_prev);
670 $this->setNumberOfNextSessions((int) $row->session_next);
671 }
672 $this->initParticipants();
673
674 // Inherit order type from parent course (if exists)
676 }
677
681 public function cloneObject(int $a_target_id, int $a_copy_id = 0, bool $a_omit_tree = false): ?ilObject
682 {
686 $new_obj = parent::cloneObject($a_target_id, $a_copy_id, $a_omit_tree);
687
688 // current template
689 $current_template = ilDidacticTemplateObjSettings::lookupTemplateId($this->getRefId());
690 $new_obj->applyDidacticTemplate($current_template);
691 $this->cloneAutoGeneratedRoles($new_obj);
692 $this->cloneMetaData($new_obj);
693
694 $new_obj->setRegistrationType($this->getRegistrationType());
695 $new_obj->setInformation($this->getInformation());
696 $new_obj->setRegistrationStart($this->getRegistrationStart());
697 $new_obj->setRegistrationEnd($this->getRegistrationEnd());
698 $new_obj->enableUnlimitedRegistration($this->isRegistrationUnlimited());
699 $new_obj->setPassword($this->getPassword());
700 $new_obj->enableMembershipLimitation($this->isMembershipLimited());
701 $new_obj->setMaxMembers($this->getMaxMembers());
702 $new_obj->enableWaitingList($this->isWaitingListEnabled());
703 $new_obj->setShowMembers($this->getShowMembers());
704
705 // map
706 $new_obj->setLatitude($this->getLatitude());
707 $new_obj->setLongitude($this->getLongitude());
708 $new_obj->setLocationZoom($this->getLocationZoom());
709 $new_obj->setEnableGroupMap($this->getEnableGroupMap());
710 $new_obj->enableRegistrationAccessCode($this->isRegistrationAccessCodeEnabled());
711 $new_obj->setRegistrationAccessCode(ilMembershipRegistrationCodeUtils::generateCode());
712
713 $new_obj->setViewMode($this->view_mode);
714 $new_obj->setMailToMembersType($this->getMailToMembersType());
715
716 $new_obj->setCancellationEnd($this->getCancellationEnd());
717 $new_obj->setMinMembers($this->getMinMembers());
718 $new_obj->setWaitingListAutoFill($this->hasWaitingListAutoFill());
719 $new_obj->setPeriod($this->getStart(), $this->getEnd());
720 $new_obj->setAutoNotification($this->getAutoNotification());
721 $new_obj->enableSessionLimit($this->isSessionLimitEnabled());
722 $new_obj->setNumberOfPreviousSessions($this->getNumberOfPreviousSessions());
723 $new_obj->setNumberOfNextSessions($this->getNumberOfNextSessions());
724 $new_obj->update();
725
726 // #13008 - Group Defined Fields
727 ilCourseDefinedFieldDefinition::_clone($this->getId(), $new_obj->getId());
728
729 // Assign user as admin
730 $part = ilGroupParticipants::_getInstanceByObjId($new_obj->getId());
731 $part->add($this->user->getId(), ilParticipants::IL_GRP_ADMIN);
732 $part->updateNotification($this->user->getId(), (bool) $this->setting->get('mail_grp_admin_notification', "1"));
733 $part->updateContact($this->user->getId(), true);
734
735 // Copy learning progress settings
736 $obj_settings = new ilLPObjSettings($this->getId());
737 $obj_settings->cloneSettings($new_obj->getId());
738 unset($obj_settings);
739 return $new_obj;
740 }
741
745 public function cloneDependencies(int $a_target_id, int $a_copy_id): bool
746 {
747 parent::cloneDependencies($a_target_id, $a_copy_id);
748
749 ilObjectActivation::cloneDependencies($this->getRefId(), $a_target_id, $a_copy_id);
750
751 // clone membership limitation
752 foreach (\ilObjCourseGrouping::_getGroupings($this->getId()) as $grouping_id) {
753 $this->logger->info('Handling grouping id: ' . $grouping_id);
754 $grouping = new \ilObjCourseGrouping($grouping_id);
755 $grouping->cloneGrouping($a_target_id, $a_copy_id);
756 }
757 return true;
758 }
759
763 public function cloneAutoGeneratedRoles(ilObjGroup $new_obj): void
764 {
765 $admin = $this->getDefaultAdminRole();
766 $new_admin = $new_obj->getDefaultAdminRole();
767 if (!$admin || !$new_admin || !$this->getRefId() || !$new_obj->getRefId()) {
768 $this->logger->warning('Error cloning auto generated rol: il_grp_admin');
769 }
770 $this->rbac_admin->copyRolePermissions($admin, $this->getRefId(), $new_obj->getRefId(), $new_admin, true);
771 $this->logger->info('Finished copying of role il_grp_admin.');
772
773 $member = $this->getDefaultMemberRole();
774 $new_member = $new_obj->getDefaultMemberRole();
775 if (!$member || !$new_member) {
776 $this->logger->warning('Error cloning auto generated rol: il_grp_member');
777 }
778 $this->rbac_admin->copyRolePermissions($member, $this->getRefId(), $new_obj->getRefId(), $new_member, true);
779 $this->logger->info('Finished copying of role il_grp_member.');
780 }
781
782
786 public function getDefaultMemberRole(): int
787 {
788 $local_group_Roles = $this->getLocalGroupRoles();
789 return $local_group_Roles["il_grp_member_" . $this->getRefId()];
790 }
791
795 public function getDefaultAdminRole(): int
796 {
797 $local_group_Roles = $this->getLocalGroupRoles();
798 return $local_group_Roles["il_grp_admin_" . $this->getRefId()];
799 }
800
801 public function leaveGroup(): int
802 {
803 $member_ids = $this->getGroupMemberIds();
804 if (count($member_ids) <= 1 || !in_array($this->user->getId(), $member_ids)) {
805 return 2;
806 } elseif (!$this->isAdmin($this->user->getId())) {
807 $this->leave($this->user->getId());
808 $this->recommended_content_manager->removeObjectRecommendation($this->user->getId(), $this->getRefId());
809 return 0;
810 } elseif (count($this->getGroupAdminIds()) == 1) {
811 return 1;
812 }
813 return 1;
814 }
815
819 public function leave(int $a_user_id): bool
820 {
821 $arr_groupRoles = $this->getMemberRoles($a_user_id);
822 foreach ($arr_groupRoles as $groupRole) {
823 $this->rbac_admin->deassignUser($groupRole, $a_user_id);
824 }
825 return true;
826 }
827
833 public function getGroupMemberIds(): array
834 {
835 $usr_arr = array();
836 $rol = $this->getLocalGroupRoles();
837 $mem_arr = [];
838 foreach ($rol as $value) {
839 foreach ($this->rbac_review->assignedUsers($value) as $member_id) {
840 array_push($usr_arr, $member_id);
841 }
842 }
843 return array_unique($usr_arr);
844 }
845
850 public function getGroupMemberData(array $a_mem_ids, int $active = 1): array
851 {
852 $usr_arr = array();
853 $q = "SELECT login,firstname,lastname,title,usr_id,last_login " .
854 "FROM usr_data " .
855 "WHERE usr_id IN (" . implode(',', ilArrayUtil::quoteArray($a_mem_ids)) . ") ";
856
857 if (is_numeric($active) && $active > -1) {
858 $q .= "AND active = '$active'";
859 }
860
861 $q .= 'ORDER BY lastname,firstname';
862
863 $r = $this->db->query($q);
864 $mem_arr = [];
865 while ($row = $r->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
866 $mem_arr[] = array("id" => (int) $row->usr_id,
867 "login" => $row->login,
868 "firstname" => $row->firstname,
869 "lastname" => $row->lastname,
870 "last_login" => $row->last_login
871 );
872 }
873
874 return $mem_arr;
875 }
876
877 public function getCountMembers(): int
878 {
879 return count($this->getGroupMemberIds());
880 }
881
882 public function getGroupAdminIds(int $a_grpId = 0): array
883 {
884 if (!empty($a_grpId)) {
885 $grp_id = $a_grpId;
886 } else {
887 $grp_id = $this->getRefId();
888 }
889
890 $usr_arr = array();
891 $roles = $this->getDefaultGroupRoles();
892
893 foreach ($this->rbac_review->assignedUsers($this->getDefaultAdminRole()) as $member_id) {
894 array_push($usr_arr, $member_id);
895 }
896 return $usr_arr;
897 }
898
903 protected function getDefaultGroupRoles(): array
904 {
905 $grp_id = $this->getRefId();
906 $role_arr = $this->rbac_review->getRolesOfRoleFolder($grp_id);
907 $arr_grpDefaultRoles = [];
908 foreach ($role_arr as $role_id) {
909 $role = ilObjectFactory::getInstanceByObjId($role_id, false);
910 $grp_Member = "il_grp_member_" . $grp_id;
911 $grp_Admin = "il_grp_admin_" . $grp_id;
912
913 if (strcmp($role->getTitle(), $grp_Member) == 0) {
914 $arr_grpDefaultRoles["grp_member_role"] = $role->getId();
915 }
916
917 if (strcmp($role->getTitle(), $grp_Admin) == 0) {
918 $arr_grpDefaultRoles["grp_admin_role"] = $role->getId();
919 }
920 }
921 return $arr_grpDefaultRoles;
922 }
923
929 public function getLocalGroupRoles(bool $a_translate = false): array
930 {
931 if (empty($this->local_roles)) {
932 $this->local_roles = array();
933 $role_arr = $this->rbac_review->getRolesOfRoleFolder($this->getRefId());
934
935 foreach ($role_arr as $role_id) {
936 if ($this->rbac_review->isAssignable($role_id, $this->getRefId()) == true) {
937 $role = ilObjectFactory::getInstanceByObjId($role_id, false);
938 if ($a_translate) {
939 $role_name = ilObjRole::_getTranslation($role->getTitle());
940 } else {
941 $role_name = $role->getTitle();
942 }
943 $this->local_roles[$role_name] = $role->getId();
944 }
945 }
946 }
947 return $this->local_roles;
948 }
949
954 {
955 $q = "SELECT obj_id FROM object_data WHERE type='rolt' AND title='il_grp_status_closed'";
956 $res = $this->ilias->db->query($q);
957 $row = $res->fetchRow(ilDBConstants::FETCHMODE_ASSOC);
958
959 return (int) $row["obj_id"];
960 }
961
966 {
967 $q = "SELECT obj_id FROM object_data WHERE type='rolt' AND title='il_grp_status_open'";
968 $res = $this->ilias->db->query($q);
969 $row = $res->fetchRow(ilDBConstants::FETCHMODE_ASSOC);
970
971 return (int) $row["obj_id"];
972 }
973
974 public static function lookupGroupStatusTemplateId(int $a_obj_id): int
975 {
976 global $DIC;
977
978 $ilDB = $DIC['ilDB'];
979
980 $type = self::lookupGroupTye($a_obj_id);
982 $query = 'SELECT obj_id FROM object_data WHERE type = ' . $ilDB->quote('rolt', 'text') . ' AND title = ' . $ilDB->quote('il_grp_status_closed', 'text');
983 } else {
984 $query = 'SELECT obj_id FROM object_data WHERE type = ' . $ilDB->quote('rolt', 'text') . ' AND title = ' . $ilDB->quote('il_grp_status_open', 'text');
985 }
986 $res = $ilDB->query($query);
987 $row = $res->fetchRow(ilDBConstants::FETCHMODE_ASSOC);
988 return $row['obj_id'] ? (int) $row['obj_id'] : 0;
989 }
990
991
992
998 public function updateGroupType(
999 int $a_group_type = ilGroupConstants::GRP_TYPE_OPEN
1000 ): void {
1001 if ($a_group_type == ilGroupConstants::GRP_TYPE_OPEN) {
1002 $this->applyDidacticTemplate(0);
1003 return;
1004 }
1005 $templates = ilDidacticTemplateSettings::getInstanceByObjectType($this->getType())->getTemplates();
1006 foreach ($templates as $template) {
1007 // the closed template
1008 if ($template->isAutoGenerated()) {
1009 $this->logger->info('Appying default closed template');
1010 $this->applyDidacticTemplate($template->getId());
1011 return;
1012 }
1013 }
1014 $this->logger->warning('No closed didactic template available.');
1015 }
1016
1017
1018 public function setGroupStatus(int $a_status): void
1019 {
1020 $this->group_status = $a_status;
1021 }
1022
1026 public function getGroupStatus(): int
1027 {
1028 return $this->group_status;
1029 }
1030
1035 public function readGroupStatus(): int
1036 {
1037 $tpl_id = ilDidacticTemplateObjSettings::lookupTemplateId($this->getRefId());
1038 if (!$tpl_id) {
1040 }
1042 }
1043
1044 public function getMemberRoles(int $a_user_id): array
1045 {
1046 return array_intersect(
1047 $this->rbac_review->assignedRoles($a_user_id),
1048 $this->getLocalGroupRoles()
1049 );
1050 }
1051
1052 public function isAdmin(int $a_userId): bool
1053 {
1054 $grp_Roles = $this->getDefaultGroupRoles();
1055 if (in_array($a_userId, $this->rbac_review->assignedUsers($grp_Roles["grp_admin_role"]))) {
1056 return true;
1057 } else {
1058 return false;
1059 }
1060 }
1064 public function initDefaultRoles(): void
1065 {
1067 'il_grp_admin_' . $this->getRefId(),
1068 "Groupadmin group obj_no." . $this->getId(),
1069 'il_grp_admin',
1070 $this->getRefId()
1071 );
1072 $this->m_roleAdminId = $role->getId();
1073
1075 'il_grp_member_' . $this->getRefId(),
1076 "Groupmember of group obj_no." . $this->getId(),
1077 'il_grp_member',
1078 $this->getRefId()
1079 );
1080 $this->m_roleMemberId = $role->getId();
1081 }
1082
1091 public function setParentRolePermissions(int $a_parent_ref): bool
1092 {
1093 $parent_roles = $this->rbac_review->getParentRoleIds($a_parent_ref);
1094 foreach ($parent_roles as $parent_role) {
1095 if ($parent_role['parent'] == $this->getRefId()) {
1096 continue;
1097 }
1098 if ($this->rbac_review->isProtected((int) $parent_role['parent'], (int) $parent_role['rol_id'])) {
1099 $operations = $this->rbac_review->getOperationsOfRole(
1100 (int) $parent_role['obj_id'],
1101 $this->getType(),
1102 (int) $parent_role['parent']
1103 );
1104 $this->rbac_admin->grantPermission(
1105 (int) $parent_role['obj_id'],
1106 $operations,
1107 $this->getRefId()
1108 );
1109 continue;
1110 }
1111
1112 $this->rbac_admin->initIntersectionPermissions(
1113 $this->getRefId(),
1114 (int) $parent_role['obj_id'],
1115 (int) $parent_role['parent'],
1116 $this->getGrpStatusOpenTemplateId(),
1118 );
1119 }
1120 return true;
1121 }
1122
1123
1127 public function applyDidacticTemplate(int $a_tpl_id): void
1128 {
1129 parent::applyDidacticTemplate($a_tpl_id);
1130
1131 if (!$a_tpl_id) {
1132 // init default type
1133 $this->setParentRolePermissions($this->getRefId());
1134 }
1135 }
1136
1137
1138 public static function _lookupIdByTitle(string $a_title): int
1139 {
1140 global $DIC;
1141
1142 $ilDB = $DIC['ilDB'];
1143 $query = "SELECT * FROM object_data WHERE title = " .
1144 $ilDB->quote($a_title, 'text') . " AND type = 'grp'";
1145 $res = $ilDB->query($query);
1146 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1147 return $row->obj_id;
1148 }
1149 return 0;
1150 }
1151
1152
1153 public function _isMember(int $a_user_id, int $a_ref_id, string $a_field = ''): bool
1154 {
1155 $local_roles = $this->rbac_review->getRolesOfRoleFolder($a_ref_id, false);
1156 $user_roles = $this->rbac_review->assignedRoles($a_user_id);
1157
1158 // Used for membership limitations -> check membership by given field
1159 if ($a_field) {
1160 $tmp_user = ilObjectFactory::getInstanceByObjId($a_user_id);
1161 if (!$tmp_user instanceof ilObjUser) {
1162 throw new DomainException('Invalid user id given: ' . $a_user_id);
1163 }
1164 switch ($a_field) {
1165 case 'login':
1166 $and = "AND login = '" . $tmp_user->getLogin() . "' ";
1167 break;
1168 case 'email':
1169 $and = "AND email = '" . $tmp_user->getEmail() . "' ";
1170 break;
1171 case 'matriculation':
1172 $and = "AND matriculation = '" . $tmp_user->getMatriculation() . "' ";
1173 break;
1174
1175 default:
1176 $and = "AND usr_id = '" . $a_user_id . "'";
1177 break;
1178 }
1179 if (!$members = ilObjGroup::_getMembers(ilObject::_lookupObjId($a_ref_id))) {
1180 return false;
1181 }
1182 $query = "SELECT * FROM usr_data as ud " .
1183 "WHERE usr_id IN (" . implode(",", ilArrayUtil::quoteArray($members)) . ") " .
1184 $and;
1185 $res = $this->db->query($query);
1186 return (bool) $res->numRows();
1187 }
1188
1189 if (!array_intersect($local_roles, $user_roles)) {
1190 return false;
1191 }
1192
1193 return true;
1194 }
1195
1196 public function _getMembers(int $a_obj_id): array
1197 {
1198 // get reference
1199 $ref_ids = ilObject::_getAllReferences($a_obj_id);
1200 $ref_id = current($ref_ids);
1201
1202 $local_roles = $this->rbac_review->getRolesOfRoleFolder($ref_id, false);
1203
1204 $users = array();
1205 foreach ($local_roles as $role_id) {
1206 $users = array_merge($users, $this->rbac_review->assignedUsers($role_id));
1207 }
1208 return array_unique($users);
1209 }
1210
1215 public function getViewMode(): int
1216 {
1217 $tree = $this->tree;
1218
1219 // default: by type
1220 $view = self::lookupViewMode($this->getId());
1221
1222 if ($view != ilContainer::VIEW_INHERIT) {
1223 return $view;
1224 }
1225
1226 $container_ref_id = $tree->checkForParentType($this->ref_id, 'crs');
1227 if ($container_ref_id) {
1228 $view_mode = ilObjCourseAccess::_lookupViewMode(ilObject::_lookupObjId($container_ref_id));
1229 // these three are available...
1230 if (
1231 $view_mode == ilContainer::VIEW_SESSIONS ||
1232 $view_mode == ilContainer::VIEW_BY_TYPE ||
1233 $view_mode == ilContainer::VIEW_SIMPLE) {
1234 return $view_mode;
1235 }
1236 }
1238 }
1239
1240
1241 public function setViewMode(int $a_view_mode): void
1242 {
1243 $this->view_mode = $a_view_mode;
1244 }
1245
1246 public static function lookupViewMode($a_obj_id): int
1247 {
1248 global $DIC;
1249
1250 $ilDB = $DIC->database();
1251
1252 $query = 'SELECT view_mode FROM grp_settings ' .
1253 'WHERE obj_id = ' . $ilDB->quote($a_obj_id, 'integer');
1254 $res = $ilDB->query($query);
1255
1256 $view_mode = null;
1257 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1258 $view_mode = (int) $row->view_mode;
1259 }
1260 return $view_mode;
1261 }
1262
1263 public static function translateViewMode(int $a_obj_id, int $a_view_mode, ?int $a_ref_id = null): int
1264 {
1265 global $DIC;
1266
1267 $tree = $DIC['tree'];
1268
1269 if (!$a_view_mode) {
1270 $a_view_mode = ilContainer::VIEW_DEFAULT;
1271 }
1272
1273 // view mode is inherit => check for parent course
1274 if ($a_view_mode == ilContainer::VIEW_INHERIT) {
1275 if (!$a_ref_id) {
1276 $ref = ilObject::_getAllReferences($a_obj_id);
1277 $a_ref_id = end($ref);
1278 }
1279
1280 $crs_ref = $tree->checkForParentType($a_ref_id, 'crs');
1281 if (!$crs_ref) {
1283 }
1284
1286
1287 // validate course view mode
1288 if (!in_array($view_mode, array(ilContainer::VIEW_SESSIONS,
1291 }
1292
1293 return $view_mode;
1294 }
1295
1296 return $a_view_mode;
1297 }
1298
1303 public function addAdditionalSubItemInformation(array &$object): void
1304 {
1306 }
1307
1308 public function getMessage(): string
1309 {
1310 return $this->message;
1311 }
1312
1313 public function setMessage(string $a_message): void
1314 {
1315 $this->message = $a_message;
1316 }
1317 public function appendMessage(string $a_message): void
1318 {
1319 if ($this->getMessage()) {
1320 $this->message .= "<br /> ";
1321 }
1322 $this->message .= $a_message;
1323 }
1324
1329 protected function prepareAppointments($a_mode = 'create'): array
1330 {
1331 switch ($a_mode) {
1332 case 'create':
1333 case 'update':
1334
1335 $apps = array();
1336 if ($this->getStart() && $this->getEnd()) {
1337 $app = new ilCalendarAppointmentTemplate(self::CAL_START);
1338 $app->setTitle($this->getTitle());
1339 $app->setSubtitle('grp_cal_start');
1340 $app->setTranslationType(ilCalendarEntry::TRANSLATION_SYSTEM);
1341 $app->setDescription($this->getLongDescription());
1342 $app->setStart($this->getStart());
1343 $app->setFullday(!$this->getStartTimeIndication());
1344 $apps[] = $app;
1345
1346 $app = new ilCalendarAppointmentTemplate(self::CAL_END);
1347 $app->setTitle($this->getTitle());
1348 $app->setSubtitle('grp_cal_end');
1349 $app->setTranslationType(ilCalendarEntry::TRANSLATION_SYSTEM);
1350 $app->setDescription($this->getLongDescription());
1351 $app->setStart($this->getEnd());
1352 $app->setFullday(!$this->getStartTimeIndication());
1353 $apps[] = $app;
1354 }
1355 if ($this->isRegistrationUnlimited()) {
1356 return $apps;
1357 }
1358
1359 $app = new ilCalendarAppointmentTemplate(self::CAL_REG_START);
1360 $app->setTitle($this->getTitle());
1361 $app->setSubtitle('grp_cal_reg_start');
1362 $app->setTranslationType(ilCalendarEntry::TRANSLATION_SYSTEM);
1363 $app->setDescription($this->getLongDescription());
1364 $app->setStart($this->getRegistrationStart());
1365 $apps[] = $app;
1366
1367 $app = new ilCalendarAppointmentTemplate(self::CAL_REG_END);
1368 $app->setTitle($this->getTitle());
1369 $app->setSubtitle('grp_cal_reg_end');
1370 $app->setTranslationType(ilCalendarEntry::TRANSLATION_SYSTEM);
1371 $app->setDescription($this->getLongDescription());
1372 $app->setStart($this->getRegistrationEnd());
1373 $apps[] = $app;
1374
1375
1376 return $apps;
1377
1378 case 'delete':
1379 // Nothing to do: The category and all assigned appointments will be deleted.
1380 return array();
1381 }
1382 return [];
1383 }
1384
1385
1386 protected function initParticipants(): void
1387 {
1388 $this->members_obj = ilGroupParticipants::_getInstanceByObjId($this->getId());
1389 }
1390
1392 {
1393 // #17886
1394 if (!$this->members_obj instanceof ilGroupParticipants) {
1395 $this->initParticipants();
1396 }
1397 return $this->members_obj;
1398 }
1399
1404 public static function lookupObjectsByCode(string $a_code): array
1405 {
1406 global $DIC;
1407
1408 $ilDB = $DIC->database();
1409
1410 $query = "SELECT obj_id FROM grp_settings " .
1411 "WHERE reg_ac_enabled = " . $ilDB->quote(1, 'integer') . " " .
1412 "AND reg_ac = " . $ilDB->quote($a_code, 'text');
1413 $res = $ilDB->query($query);
1414
1415 $obj_ids = array();
1416 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1417 $obj_ids[] = (int) $row->obj_id;
1418 }
1419 return $obj_ids;
1420 }
1421
1426 public function register(
1427 int $a_user_id,
1428 int $a_role = ilParticipants::IL_GRP_MEMBER,
1429 bool $a_force_registration = false
1430 ): void {
1432
1433 if ($part->isAssigned($a_user_id)) {
1434 return;
1435 }
1436
1437 if (!$a_force_registration) {
1438 // Availability
1439 if (!$this->isRegistrationEnabled()) {
1441 throw new ilMembershipRegistrationException('Cannot registrate to group ' . $this->getId() .
1442 ', group subscription is deactivated.', ilMembershipRegistrationException::REGISTRATION_CODE_DISABLED);
1443 }
1444 }
1445
1446 // Time Limitation
1447 if (!$this->isRegistrationUnlimited()) {
1448 $start = $this->getRegistrationStart();
1449 $end = $this->getRegistrationEnd();
1450 $time = new ilDateTime(time(), IL_CAL_UNIX);
1451
1452 if (!(ilDateTime::_after($time, $start) and ilDateTime::_before($time, $end))) {
1453 throw new ilMembershipRegistrationException('Cannot registrate to group ' . $this->getId() .
1454 ', group is out of registration time.', ilMembershipRegistrationException::OUT_OF_REGISTRATION_PERIOD);
1455 }
1456 }
1457
1458 // Max members
1459 if ($this->isMembershipLimited()) {
1460 $free = max(0, $this->getMaxMembers() - $part->getCountMembers());
1461 $waiting_list = new ilGroupWaitingList($this->getId());
1462 if ($this->isWaitingListEnabled() and (!$free or $waiting_list->getCountUsers())) {
1463 $this->lng->loadLanguageModule("grp");
1464 $waiting_list->addToList($a_user_id);
1465
1466 $info = sprintf(
1467 $this->lng->txt('grp_added_to_list'),
1468 $this->getTitle(),
1469 $waiting_list->getPosition($a_user_id)
1470 );
1471
1472 $participants = ilGroupParticipants::_getInstanceByObjId($this->getId());
1473 $participants->sendNotification(ilGroupMembershipMailNotification::TYPE_WAITING_LIST_MEMBER, $a_user_id);
1474
1476 }
1477
1478 if (!$free or $waiting_list->getCountUsers()) {
1479 throw new ilMembershipRegistrationException('Cannot registrate to group ' . $this->getId() .
1480 ', membership is limited.', ilMembershipRegistrationException::OBJECT_IS_FULL);
1481 }
1482 }
1483 }
1484
1485 $part->add($a_user_id, $a_role);
1486 $part->sendNotification(ilGroupMembershipMailNotification::TYPE_ADMISSION_MEMBER, $a_user_id);
1487 $part->sendNotification(ilGroupMembershipMailNotification::TYPE_NOTIFICATION_REGISTRATION, $a_user_id);
1488 }
1489
1490 public function handleAutoFill(): void
1491 {
1492 if ($this->isWaitingListEnabled() &&
1493 $this->hasWaitingListAutoFill()) {
1494 $max = $this->getMaxMembers();
1495 $now = ilGroupParticipants::lookupNumberOfMembers($this->getRefId());
1496 if ($max > $now) {
1497 // see assignFromWaitingListObject()
1498 $waiting_list = new ilGroupWaitingList($this->getId());
1499
1500 foreach ($waiting_list->getUserIds() as $user_id) {
1501 if (!$tmp_obj = ilObjectFactory::getInstanceByObjId($user_id, false)) {
1502 continue;
1503 }
1504 if ($this->getMembersObject()->isAssigned($user_id)) {
1505 continue;
1506 }
1507 $this->getMembersObject()->add($user_id, ilParticipants::IL_GRP_MEMBER); // #18213
1508 $this->getMembersObject()->sendNotification(ilGroupMembershipMailNotification::TYPE_ACCEPTED_SUBSCRIPTION_MEMBER, $user_id, true);
1509 $waiting_list->removeFromList($user_id);
1510
1511 $now++;
1512 if ($now >= $max) {
1513 break;
1514 }
1515 }
1516 }
1517 }
1518 }
1519
1520 public static function mayLeave(int $a_group_id, ?int $a_user_id = null, ?ilDate &$a_date = null): bool
1521 {
1522 global $DIC;
1523
1524 $ilUser = $DIC->user();
1525 $ilDB = $DIC->database();
1526
1527 if (!$a_user_id) {
1528 $a_user_id = $ilUser->getId();
1529 }
1530
1531 $set = $ilDB->query("SELECT leave_end" .
1532 " FROM grp_settings" .
1533 " WHERE obj_id = " . $ilDB->quote($a_group_id, "integer"));
1534 $row = $ilDB->fetchAssoc($set);
1535 if ($row && isset($row["leave_end"]) && is_numeric($row["leave_end"])) {
1536 // timestamp to date
1537 $limit = date("Ymd", (int) $row["leave_end"]);
1538 if ($limit < date("Ymd")) {
1539 $a_date = new ilDate(date("Y-m-d", (int) $row["leave_end"]), IL_CAL_DATE);
1540 return false;
1541 }
1542 }
1543 return true;
1544 }
1545
1546 public static function findGroupsWithNotEnoughMembers(): array
1547 {
1548 global $DIC;
1549 $ilDB = $DIC->database();
1550 $tree = $DIC->repositoryTree();
1551
1552 $res = array();
1553 $before = new ilDateTime(time(), IL_CAL_UNIX);
1554 $now_date = $before->get(IL_CAL_DATETIME, '', ilTimeZone::UTC);
1555 /*
1556 * For groups, registration_start and registration_end are currently not
1557 * persisted in UTC but the local timezone, so when fetching the current time
1558 * here we need to do the same.
1559 */
1560 $now_date_local = $before->get(IL_CAL_DATETIME);
1561 $now = $before->get(IL_CAL_UNIX);
1562
1563 $set = $ilDB->query($q = "SELECT obj_id, registration_min_members" .
1564 " FROM grp_settings" .
1565 " WHERE registration_min_members > " . $ilDB->quote(0, "integer") .
1566 " AND registration_mem_limit = " . $ilDB->quote(1, "integer") . // #17206
1567 " AND ((leave_end IS NOT NULL" .
1568 " AND leave_end < " . $ilDB->quote($now, "integer") . ")" .
1569 " OR (leave_end IS NULL" .
1570 " AND registration_end IS NOT NULL" .
1571 " AND registration_end < " . $ilDB->quote($now_date_local, "text") . "))" .
1572 " AND (period_start IS NULL OR period_start > " . $ilDB->quote($now_date, ilDBConstants::T_TEXT) . ")");
1573 while ($row = $ilDB->fetchAssoc($set)) {
1574 $refs = ilObject::_getAllReferences((int) $row['obj_id']);
1575 $ref = end($refs);
1576
1577 if ($tree->isDeleted($ref)) {
1578 continue;
1579 }
1580
1581 $part = new ilGroupParticipants((int) $row["obj_id"]);
1582 $reci = $part->getNotificationRecipients();
1583 if (sizeof($reci)) {
1584 $missing = (int) $row["registration_min_members"] - $part->getCountMembers();
1585 if ($missing > 0) {
1586 $res[(int) $row["obj_id"]] = array($missing, $reci);
1587 }
1588 }
1589 }
1590 return $res;
1591 }
1592
1593 public static function lookupShowMembersEnabled(int $a_obj_id): bool
1594 {
1595 global $DIC;
1596 $ilDB = $DIC->database();
1597
1598 $query = 'SELECT show_members FROM grp_settings'
1599 . ' WHERE obj_id = ' . $ilDB->quote($a_obj_id, 'integer');
1600 $res = $ilDB->query($query);
1601 if ($ilDB->numRows($res) == 0) {
1602 return false;
1603 }
1604 $row = $ilDB->fetchAssoc($res);
1605 return (bool) $row['show_members'];
1606 }
1607} //END class.ilObjGroup
const IL_CAL_DATE
const IL_CAL_UNIX
const IL_CAL_DATETIME
error(string $a_errmsg)
static quoteArray(array $a_array)
Quotes all members of an array for usage in DB query statement.
Apointment templates are used for automatic generated apointments.
static convertDateToUtcDBTimestamp(?\ilDateTime $date=null)
Class ilContainer.
setOrderType(int $a_value)
static _clone(int $a_source_id, int $a_target_id)
@classDescription Date and time handling
static _after(ilDateTime $start, ilDateTime $end, string $a_compare_field='', string $a_tz='')
compare two dates and check start is after end This method does not consider tz offsets.
static _before(ilDateTime $start, ilDateTime $end, string $a_compare_field='', string $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets.
Class for single dates.
static getInstanceByObjectType(string $a_obj_type)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getInstanceByObjId(int $a_obj_id)
Get singleton instance.
Waiting list for groups.
Component logger with individual log levels by component id.
static generateCode()
Generate new registration key.
static _lookupViewMode(int $a_id)
static _getGroupings(int $a_course_id)
static _lookupViewMode(int $a_id)
Class ilObjGroup.
getLocalGroupRoles(bool $a_translate=false)
get ALL local roles of group, also those created and defined afterwards only fetch data once from dat...
enableMembershipLimitation(bool $a_status)
static lookupViewMode($a_obj_id)
applyDidacticTemplate(int $a_tpl_id)
@inheritDoc
appendMessage(string $a_message)
setRegistrationAccessCode(string $a_code)
static _lookupIdByTitle(string $a_title)
const ERR_MISSING_TITLE
getDefaultAdminRole()
returns object id of created default adminstrator role
static mayLeave(int $a_group_id, ?int $a_user_id=null, ?ilDate &$a_date=null)
getGroupMemberIds()
get all group Member ids regardless of role
ilDateTime $reg_end
getDefaultMemberRole()
returns object id of created default member role
string $information
enableWaitingList(bool $a_status)
static lookupShowMembersEnabled(int $a_obj_id)
setRegistrationEnd(?ilDateTime $a_end)
setPassword(string $a_pass)
setMessage(string $a_message)
__construct(int $a_id=0, bool $a_call_by_reference=true)
@inheritDoc
const MAIL_ALLOWED_TUTORS
string $reg_password
getMemberRoles(int $a_user_id)
bool $auto_notification
setAutoNotification(bool $a_status)
updateGroupType(int $a_group_type=ilGroupConstants::GRP_TYPE_OPEN)
Change group type Revokes permissions of all parent non-protected roles and initiates these roles wit...
readGroupStatus()
Read group type.
setEnableGroupMap(bool $a_enablemap)
setGroupType(int $a_type)
ilDateTime $grp_end
setEnd(?ilDateTime $a_value=null)
cloneAutoGeneratedRoles(ilObjGroup $new_obj)
Clone group admin and member role permissions.
getGrpStatusClosedTemplateId()
get group status closed template
create()
@inheritDoc
const ERR_WRONG_REG_TIME_LIMIT
static lookupGroupStatusTemplateId(int $a_obj_id)
addAdditionalSubItemInformation(array &$object)
Add additional information to sub item, e.g.
static lookupGroupTye(int $a_id)
const ERR_MISSING_MIN_MAX_MEMBERS
setLocationZoom(int $a_locationzoom)
setParentRolePermissions(int $a_parent_ref)
This method is called before "initDefaultRoles".
bool $auto_fill_from_waiting
getGroupAdminIds(int $a_grpId=0)
static lookupObjectsByCode(string $a_code)
setCancellationEnd(?ilDate $a_value)
bool $start_time_indication
read()
@inheritDoc
setStart(?ilDateTime $a_value=null)
bool $reg_membership_limitation
setRegistrationType(int $a_type)
setGroupStatus(int $a_status)
update()
@inheritDoc
setInformation(string $a_information)
_getMembers(int $a_obj_id)
const ERR_WRONG_REGISTRATION_LIMITED
_isMember(int $a_user_id, int $a_ref_id, string $a_field='')
validate()
validate group settings
enableRegistrationAccessCode(bool $a_status)
getViewMode()
Get effective container view mode.
getGroupMemberData(array $a_mem_ids, int $active=1)
get all group Members regardless of group role.
getGroupStatus()
get group status
const ERR_MISSING_GROUP_TYPE
setLongitude(string $a_longitude)
const ERR_MISSING_PASSWORD
setMinMembers(int $a_max)
setNumberOfNextSessions(int $a_num)
const ERR_WRONG_MIN_MAX_MEMBERS
static translateViewMode(int $a_obj_id, int $a_view_mode, ?int $a_ref_id=null)
setMailToMembersType(int $a_type)
isRegistrationAccessCodeEnabled()
getGrpStatusOpenTemplateId()
get group status open template
setViewMode(int $a_view_mode)
const MAIL_ALLOWED_ALL
ilDateTime $reg_start
static findGroupsWithNotEnoughMembers()
setPeriod(?\ilDateTime $start=null, ?\ilDateTime $end=null)
string $reg_access_code
setWaitingListAutoFill(bool $a_value)
ilDateTime $grp_start
enableSessionLimit(bool $a_status)
prepareAppointments($a_mode='create')
Prepare calendar appointments.
cloneDependencies(int $a_target_id, int $a_copy_id)
@inheritDoc
setShowMembers(bool $a_status)
setNumberOfPreviousSessions(int $a_num)
bool $reg_access_code_enabled
toggleStartTimeIndication(bool $time_indication)
setRegistrationStart(?ilDateTime $a_start)
leave(int $a_user_id)
deassign member from group role
ilGroupParticipants $members_obj
getDefaultGroupRoles()
get default group roles, returns the defaultlike create roles il_grp_member, il_grp_admin
const ERR_WRONG_MAX_MEMBERS
setMaxMembers(int $a_max)
ilLogger $logger
enableUnlimitedRegistration(bool $a_status)
setLatitude(string $a_latitude)
isAdmin(int $a_userId)
initDefaultRoles()
@inheritDoc
static createDefaultRole(string $a_title, string $a_description, string $a_tpl_name, int $a_ref_id)
static _getTranslation(string $a_role_title)
User class.
static cloneDependencies(int $ref_id, int $target_id, int $copy_id)
static addAdditionalSubItemInformation(array &$item)
Parse item data for list entries.
static getInstanceByObjId(?int $obj_id, bool $stop_on_error=true)
get an instance of an Ilias object by object id
Class ilObject Basic functions for all objects.
cloneMetaData(ilObject $target_obj)
Copy meta data.
static _getAllReferences(int $id)
get all reference ids for object ID
ilTree $tree
string $type
static _lookupObjId(int $ref_id)
static lookupNumberOfMembers(int $a_ref_id)
Lookup number of members.
static _deleteAllEntries(int $a_obj_id)
Delete all entries Normally called in case of object deletion.
const ROLE_FOLDER_ID
Definition: constants.php:34
$info
Definition: entry_point.php:21
Interface for all objects that offer registration with access codes.
$ref_id
Definition: ltiauth.php:66
$res
Definition: ltiservices.php:69
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Class ilObjForumAdministration.
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26
$q
Definition: shib_logout.php:23
$message
Definition: xapiexit.php:31