ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilObjCourse.php
Go to the documentation of this file.
1<?php
2
24{
25 public const int CAL_REG_START = 1;
26 public const int CAL_REG_END = 2;
27 public const int CAL_ACTIVATION_START = 3;
28 public const int CAL_ACTIVATION_END = 4;
29 public const int CAL_COURSE_START = 5;
30 public const int CAL_COURSE_END = 6;
31 public const int CAL_COURSE_TIMING_START = 7;
32 public const int CAL_COURSE_TIMING_END = 8;
33
34 public const int STATUS_DETERMINATION_LP = 1;
35 public const int STATUS_DETERMINATION_MANUAL = 2;
36
37 private string $contact_consultation = '';
38 private string $contact_phone = '';
39 private string $contact_email = '';
40 private string $contact_name = '';
41 private string $contact_responsibility = '';
43 private int $subscription_start = 0;
44 private int $subscription_end = 0;
45 private int $subscription_type = 0;
46 private string $subscription_password = '';
47 private int $view_mode = 0;
48 private bool $waiting_list = false;
51 private bool $abo = true;
52 private bool $show_members = true;
53 private string $message = '';
54 private bool $course_start_time_indication = true;
56 private string $important = '';
57 private string $syllabus = '';
59 private string $latitude = '';
60 private string $longitude = '';
61 private int $locationzoom = 0;
62 private bool $enablemap = false;
63
64 private int $session_limit = 0;
65 private int $session_prev = -1;
66 private int $session_next = -1;
67
68 private string $reg_access_code = '';
69 private bool $reg_access_code_enabled = false;
70 private int $status_dt = 0;
71
73
74 private bool $crs_start_time_indication = false;
75
76 private ?ilDateTime $crs_start = null;
77 private ?ilDateTime $crs_end = null;
78 private ?ilDate $leave_end = null;
79 private int $min_members = 0;
80 private bool $auto_fill_from_waiting = false;
81 private bool $member_export = false;
84 private bool $auto_notification = true;
85 private ?string $target_group = null;
86 private int $activation_start = 0;
87 private int $activation_end = 0;
88 private bool $activation_visibility = false;
89
92
93 private array $local_roles = [];
94
95 public function __construct(int $a_id = 0, bool $a_call_by_reference = true)
96 {
97 global $DIC;
98
99 $this->setStatusDetermination(self::STATUS_DETERMINATION_LP);
100
101 $this->type = "crs";
102 $this->course_logger = $DIC->logger()->crs();
103 parent::__construct($a_id, $a_call_by_reference);
104 }
105
106 public static function lookupTutorialBlockSettingEabled(int $a_obj_id): bool
107 {
108 $query = 'SELECT tutorial_support_block FROM crs_settings'
109 . ' WHERE obj_id = ' . $GLOBALS['DIC']['ilDB']->quote($a_obj_id, 'integer');
110 $res = $GLOBALS['DIC']['ilDB']->query($query);
111 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
112 return (bool) $row->tutorial_support_block;
113 }
114 return false;
115 }
116
117 public static function lookupShowMembersEnabled(int $a_obj_id): bool
118 {
119 $query = 'SELECT show_members FROM crs_settings ' .
120 'WHERE obj_id = ' . $GLOBALS['DIC']['ilDB']->quote($a_obj_id, 'integer');
121 $res = $GLOBALS['DIC']['ilDB']->query($query);
122 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
123 return (bool) $row->show_members;
124 }
125 return false;
126 }
127
128 public function getShowMembersExport(): bool
129 {
131 }
132
133 public function setShowMembersExport(bool $a_mem_export): void
134 {
135 $this->member_export = $a_mem_export;
136 }
137
138 public function getRegistrationAccessCode(): string
139 {
141 }
142
143 public function setRegistrationAccessCode(string $a_code): void
144 {
145 $this->reg_access_code = $a_code;
146 }
147
148 public function isRegistrationAccessCodeEnabled(): bool
149 {
151 }
152
153 public function enableRegistrationAccessCode(bool $a_status): void
154 {
155 $this->reg_access_code_enabled = $a_status;
156 }
157
158 public function getImportantInformation(): string
159 {
160 return $this->important;
161 }
162
163 public function setImportantInformation(string $a_info): void
164 {
165 $this->important = $a_info;
166 }
167
168 public function getSyllabus(): string
169 {
170 return $this->syllabus;
171 }
172
173 public function setSyllabus(string $a_syllabus): void
174 {
175 $this->syllabus = $a_syllabus;
176 }
177
178 public function getTargetGroup(): ?string
179 {
180 return $this->target_group;
181 }
182
183 public function setTargetGroup(?string $a_tg): void
184 {
185 $this->target_group = $a_tg;
186 }
187
188 public function getContactName(): string
189 {
190 return $this->contact_name;
191 }
192
193 public function setContactName(string $a_cn): void
194 {
195 $this->contact_name = $a_cn;
196 }
197
198 public function getContactConsultation(): string
199 {
201 }
202
203 public function setContactConsultation(string $a_value): void
204 {
205 $this->contact_consultation = $a_value;
206 }
207
208 public function getContactPhone(): string
209 {
211 }
212
213 public function setContactPhone(string $a_value): void
214 {
215 $this->contact_phone = $a_value;
216 }
217
218 public function getContactEmail(): string
219 {
221 }
222
223 public function setContactEmail(string $a_value): void
224 {
225 $this->contact_email = $a_value;
226 }
227
228 public function getContactResponsibility(): string
229 {
231 }
232
233 public function setContactResponsibility(string $a_value): void
234 {
235 $this->contact_responsibility = $a_value;
236 }
237
238 public function getActivationUnlimitedStatus(): bool
239 {
240 return !$this->getActivationStart() || !$this->getActivationEnd();
241 }
242
243 public function getActivationStart(): int
244 {
246 }
247
248 public function setActivationStart(int $a_value): void
249 {
250 $this->activation_start = $a_value;
251 }
252
253 public function getActivationEnd(): int
254 {
256 }
257
258 public function setActivationEnd(int $a_value): void
259 {
260 $this->activation_end = $a_value;
261 }
262
263 public function setActivationVisibility(bool $a_value): void
264 {
265 $this->activation_visibility = $a_value;
266 }
267
268 public function getActivationVisibility(): bool
269 {
271 }
272
274 {
276 }
277
278 public function setSubscriptionLimitationType(int $a_type): void
279 {
280 $this->subscription_limitation_type = $a_type;
281 }
282
283 public function getSubscriptionUnlimitedStatus(): bool
284 {
285 return $this->subscription_limitation_type == ilCourseConstants::IL_CRS_SUBSCRIPTION_UNLIMITED;
286 }
287
288 public function getSubscriptionStart(): int
289 {
291 }
292
293 public function setSubscriptionStart(int $a_value): void
294 {
295 $this->subscription_start = $a_value;
296 }
297
298 public function getSubscriptionEnd(): int
299 {
301 }
302
303 public function setSubscriptionEnd(int $a_value): void
304 {
305 $this->subscription_end = $a_value;
306 }
307
308 public function getSubscriptionType(): int
309 {
310 return $this->subscription_type ?: ilCourseConstants::IL_CRS_SUBSCRIPTION_DIRECT;
311 }
312
313 public function setSubscriptionType(int $a_value): void
314 {
315 $this->subscription_type = $a_value;
316 }
317
318 public function getSubscriptionPassword(): string
319 {
321 }
322
323 public function setSubscriptionPassword(string $a_value): void
324 {
325 $this->subscription_password = $a_value;
326 }
327
328 public function enabledObjectiveView(): bool
329 {
330 return $this->view_mode == ilCourseConstants::IL_CRS_VIEW_OBJECTIVE;
331 }
332
333 public function enabledWaitingList(): bool
334 {
335 return $this->waiting_list;
336 }
337
338 public function enableWaitingList(bool $a_status): void
339 {
340 $this->waiting_list = $a_status;
341 }
342
343 public function inSubscriptionTime(): bool
344 {
345 if ($this->getSubscriptionUnlimitedStatus()) {
346 return true;
347 }
348 if (time() > $this->getSubscriptionStart() and time() < $this->getSubscriptionEnd()) {
349 return true;
350 }
351 return false;
352 }
353
354 public function enableSessionLimit(int $a_status): void
355 {
356 $this->session_limit = $a_status;
357 }
358
359 public function isSessionLimitEnabled(): bool
360 {
361 return (bool) $this->session_limit;
362 }
363
364 public function enableSubscriptionMembershipLimitation(bool $a_status): void
365 {
366 $this->subscription_membership_limitation = $a_status;
367 }
368
369 public function setNumberOfPreviousSessions(int $a_num): void
370 {
371 $this->session_prev = $a_num;
372 }
373
375 {
376 return $this->session_prev;
377 }
378
379 public function setNumberOfNextSessions(int $a_num): void
380 {
381 $this->session_next = $a_num;
382 }
383
384 public function getNumberOfNextSessions(): int
385 {
386 return $this->session_next;
387 }
388
389 public function isSubscriptionMembershipLimited(): bool
390 {
392 }
393
395 {
397 }
398
399 public function setSubscriptionMaxMembers(int $a_value): void
400 {
401 $this->subscription_max_members = $a_value;
402 }
403
404 public static function _isSubscriptionNotificationEnabled(int $a_course_id): bool
405 {
406 global $DIC;
407
408 $ilDB = $DIC->database();
409 $query = "SELECT * FROM crs_settings " .
410 "WHERE obj_id = " . $ilDB->quote($a_course_id, 'integer') . " " .
411 "AND sub_notify = 1";
412 $res = $ilDB->query($query);
413 return (bool) $res->numRows();
414 }
415
416 public function getSubscriptionNotify(): bool
417 {
418 return true;
419 }
420
421 public function setViewMode(int $a_mode): void
422 {
423 $this->view_mode = $a_mode;
424 }
425
426 public function getViewMode(): int
427 {
428 return $this->view_mode;
429 }
430
431 public static function lookupTimingMode(int $a_obj_id): int
432 {
433 global $DIC;
434
435 $ilDB = $DIC['ilDB'];
436
437 $query = 'SELECT timing_mode FROM crs_settings ' .
438 'WHERE obj_id = ' . $ilDB->quote($a_obj_id, 'integer');
439 $res = $ilDB->query($query);
440
441 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
442 return (int) $row->timing_mode;
443 }
445 }
446
447 public function setTimingMode(int $a_mode): void
448 {
449 $this->timing_mode = $a_mode;
450 }
451
452 public function getTimingMode(): int
453 {
454 return $this->timing_mode;
455 }
456
457 public function setTutorialSupportBlockSettingValue(int $value): void
458 {
459 $this->tutorial_support_block_setting_value = $value;
460 }
461
463 {
465 }
466
467 public static function _lookupViewMode(int $a_id): int
468 {
469 global $DIC;
470
471 $ilDB = $DIC['ilDB'];
472
473 $query = "SELECT view_mode FROM crs_settings WHERE obj_id = " . $ilDB->quote($a_id, 'integer') . " ";
474 $res = $ilDB->query($query);
475 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
476 return $row->view_mode;
477 }
478 return false;
479 }
480
481 public static function _lookupAboStatus(int $a_id): bool
482 {
483 global $DIC;
484
485 $ilDB = $DIC['ilDB'];
486
487 $query = "SELECT abo FROM crs_settings WHERE obj_id = " . $ilDB->quote($a_id, 'integer') . " ";
488 $res = $ilDB->query($query);
489 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
490 return $row->abo;
491 }
492 return false;
493 }
494
495 public function setAboStatus(bool $a_status): void
496 {
497 $this->abo = $a_status;
498 }
499
500 public function getAboStatus(): bool
501 {
502 return $this->abo;
503 }
504
505 public function setShowMembers(bool $a_status): void
506 {
507 $this->show_members = $a_status;
508 }
509
510 public function getShowMembers(): bool
511 {
512 return $this->show_members;
513 }
514
515 public function setMailToMembersType(int $a_type): void
516 {
517 $this->mail_members = $a_type;
518 }
519
520 public function getMailToMembersType(): int
521 {
522 return $this->mail_members;
523 }
524
525 public function getMessage(): string
526 {
527 return $this->message;
528 }
529
530 public function setMessage(string $a_message): void
531 {
532 $this->message = $a_message;
533 }
534
535 public function appendMessage(string $a_message): void
536 {
537 if ($this->getMessage()) {
538 $this->message .= "<br /> ";
539 }
540 $this->message .= $a_message;
541 }
542
543 public function isActivated(): bool
544 {
545 if ($this->getOfflineStatus()) {
546 return false;
547 }
548 if ($this->getActivationUnlimitedStatus()) {
549 return true;
550 }
551 if (time() < $this->getActivationStart() or
552 time() > $this->getActivationEnd()) {
553 return false;
554 }
555 return true;
556 }
557
561 public static function _isActivated(int $a_obj_id): bool
562 {
563 return ilObjCourseAccess::_isActivated($a_obj_id);
564 }
565
569 public static function _registrationEnabled(int $a_obj_id): bool
570 {
572 }
573
574 public function read(): void
575 {
576 parent::read();
578 $this->__readSettings();
579 }
580
581 public function create(): int
582 {
583 global $DIC;
584
585 $ilAppEventHandler = $DIC['ilAppEventHandler'];
586
587 $id = parent::create();
588
589 $this->createMetaData();
591 $this->app_event_handler->raise(
592 'components/ILIAS/Course',
593 'create',
594 array('object' => $this,
595 'obj_id' => $this->getId(),
596 'appointments' => $this->prepareAppointments('create')
597 )
598 );
599
600 return $id;
601 }
602
603 public function setLatitude(string $a_latitude): void
604 {
605 $this->latitude = $a_latitude;
606 }
607
608 public function getLatitude(): string
609 {
610 return $this->latitude;
611 }
612
613 public function setLongitude(string $a_longitude): void
614 {
615 $this->longitude = $a_longitude;
616 }
617
618 public function getLongitude(): string
619 {
620 return $this->longitude;
621 }
622
623 public function setLocationZoom(int $a_locationzoom): void
624 {
625 $this->locationzoom = $a_locationzoom;
626 }
627
628 public function getLocationZoom(): int
629 {
630 return $this->locationzoom;
631 }
632
633 public function setEnableCourseMap(bool $a_enablemap): void
634 {
635 $this->enablemap = $a_enablemap;
636 }
637
638 public function getEnableMap(): bool
639 {
640 return $this->getEnableCourseMap();
641 }
642
643 public function getEnableCourseMap(): bool
644 {
645 return $this->enablemap;
646 }
647
648 public function setCoursePeriod(?ilDateTime $start = null, ?ilDateTime $end = null): void
649 {
650 if (
651 ($start instanceof \ilDate && !$end instanceof ilDate) ||
652 ($end instanceof \ilDate && !$start instanceof ilDate)
653 ) {
654 throw new InvalidArgumentException('Different date types not supported.');
655 }
656
657 if ($start instanceof \ilDate) {
659 } else {
661 }
662 $this->setCourseStart($start);
663 $this->setCourseEnd($end);
664 }
665
666 protected function toggleCourseStartTimeIndication(bool $time_indication): void
667 {
668 $this->course_start_time_indication = $time_indication;
669 }
670
671 public function getCourseStartTimeIndication(): bool
672 {
674 }
675
676 protected function setCourseStart(?ilDateTime $a_value = null): void
677 {
678 $this->crs_start = $a_value;
679 }
680
681 public function getCourseStart(): ?ilDateTime
682 {
683 return $this->crs_start;
684 }
685
686 protected function setCourseEnd(?ilDateTime $a_value = null): void
687 {
688 $this->crs_end = $a_value;
689 }
690
691 public function getCourseEnd(): ?ilDateTime
692 {
693 return $this->crs_end;
694 }
695
696 public function setCancellationEnd(?ilDate $a_value = null): void
697 {
698 $this->leave_end = $a_value;
699 }
700
701 public function getCancellationEnd(): ?ilDate
702 {
703 return $this->leave_end;
704 }
705
706 public function setSubscriptionMinMembers(int $a_value): void
707 {
708 if ($a_value !== null) {
709 $a_value = $a_value;
710 }
711 $this->min_members = $a_value;
712 }
713
715 {
716 return $this->min_members;
717 }
718
719 public function setWaitingListAutoFill(bool $a_value): void
720 {
721 $this->auto_fill_from_waiting = $a_value;
722 }
723
724 public function hasWaitingListAutoFill(): bool
725 {
727 }
728
732 public function cloneObject(int $target_id, int $copy_id = 0, bool $omit_tree = false): ?ilObject
733 {
734 global $DIC;
735
736 $new_obj = parent::cloneObject($target_id, $copy_id, $omit_tree);
737
738 $this->cloneAutoGeneratedRoles($new_obj);
739 $this->cloneMetaData($new_obj);
740
741 $new_obj->getMemberObject()->add($this->user->getId(), ilParticipants::IL_CRS_ADMIN);
742 $new_obj->getMemberObject()->updateContact($this->user->getId(), 1);
743
744 $cwo = ilCopyWizardOptions::_getInstance($copy_id);
745 if ($cwo->isRootNode($this->getRefId())) {
746 $this->setOfflineStatus(true);
747 }
748
749 $this->cloneSettings($new_obj);
750 ilCourseDefinedFieldDefinition::_clone($this->getId(), $new_obj->getId());
751 ilCourseFile::_cloneFiles($this->getId(), $new_obj->getId());
752 $obj_settings = new ilLPObjSettings($this->getId());
753 $obj_settings->cloneSettings($new_obj->getId());
754 unset($obj_settings);
755 $pathFactory = new ilCertificatePathFactory();
756 $templateRepository = new ilCertificateTemplateDatabaseRepository($this->db);
757
758 $cloneAction = new ilCertificateCloneAction(
759 $this->db,
760 $pathFactory,
761 $templateRepository,
763 );
764 $cloneAction->cloneCertificate($this, $new_obj);
765
766 $book_service = new ilBookingService();
767 $book_service->cloneSettings($this->getId(), $new_obj->getId());
768
769 $badges = ilBadge::getInstancesByParentId($this->getId());
770 foreach ($badges as $badge) {
771 $badge->clone($new_obj->getId());
772 }
773
774 return $new_obj;
775 }
776
780 public function cloneDependencies(int $target_id, int $copy_id): bool
781 {
782 parent::cloneDependencies($target_id, $copy_id);
783
784 // Clone course start objects
785 $start = new ilContainerStartObjects($this->getRefId(), $this->getId());
786 $start->cloneDependencies($target_id, $copy_id);
787
788 // Clone course item settings
789 ilObjectActivation::cloneDependencies($this->getRefId(), $target_id, $copy_id);
790
791 // clone objective settings
792 ilLOSettings::cloneSettings($copy_id, $this->getId(), ilObject::_lookupObjId($target_id));
793
794 // Clone course learning objectives
795 $crs_objective = new ilCourseObjective($this);
796 $crs_objective->ilClone($target_id, $copy_id);
797
798 // clone membership limitation
799 foreach (\ilObjCourseGrouping::_getGroupings($this->getId()) as $grouping_id) {
800 $this->course_logger->info('Handling grouping id: ' . $grouping_id);
801 $grouping = new \ilObjCourseGrouping($grouping_id);
802 $grouping->cloneGrouping($target_id, $copy_id);
803 }
804 return true;
805 }
806
810 public function cloneAutoGeneratedRoles(ilObject $new_obj): void
811 {
812 $admin = $this->getDefaultAdminRole();
813 $new_admin = $new_obj->getDefaultAdminRole();
814
815 if (!$admin || !$new_admin || !$this->getRefId() || !$new_obj->getRefId()) {
816 $this->course_logger->debug('Error cloning auto generated role: il_crs_admin');
817 }
818 $this->rbac_admin->copyRolePermissions($admin, $this->getRefId(), $new_obj->getRefId(), $new_admin, true);
819 $this->course_logger->debug('Finished copying of role crs_admin.');
820
821 $tutor = $this->getDefaultTutorRole();
822 $new_tutor = $new_obj->getDefaultTutorRole();
823 if (!$tutor || !$new_tutor) {
824 $this->course_logger->info('Error cloning auto generated role: il_crs_tutor');
825 }
826 $this->rbac_admin->copyRolePermissions($tutor, $this->getRefId(), $new_obj->getRefId(), $new_tutor, true);
827 $this->course_logger->info('Finished copying of role crs_tutor.');
828
829 $member = $this->getDefaultMemberRole();
830 $new_member = $new_obj->getDefaultMemberRole();
831 if (!$member || !$new_member) {
832 $this->course_logger->debug('Error cloning auto generated role: il_crs_member');
833 }
834 $this->rbac_admin->copyRolePermissions($member, $this->getRefId(), $new_obj->getRefId(), $new_member, true);
835 $this->course_logger->debug('Finished copying of role crs_member.');
836 }
837
838 public function validate(): bool
839 {
840 $this->setMessage('');
841
843 $this->getSubscriptionStart() > $this->getSubscriptionEnd()) {
844 $this->appendMessage($this->lng->txt("subscription_times_not_valid"));
845 }
847 $this->appendMessage($this->lng->txt("crs_password_required"));
848 }
849 if ($this->isSubscriptionMembershipLimited()) {
850 if ($this->getSubscriptionMinMembers() <= 0 && $this->getSubscriptionMaxMembers() <= 0) {
851 $this->appendMessage($this->lng->txt("crs_max_and_min_members_needed"));
852 }
853 if ($this->getSubscriptionMaxMembers() <= 0 && $this->enabledWaitingList()) {
854 $this->appendMessage($this->lng->txt("crs_max_members_needed"));
855 }
856 if ($this->getSubscriptionMaxMembers() > 0 && $this->getSubscriptionMinMembers() > $this->getSubscriptionMaxMembers()) {
857 $this->appendMessage($this->lng->txt("crs_max_and_min_members_invalid"));
858 }
859 }
860 if (!$this->getTitle() || !$this->getStatusDetermination()) {
861 $this->appendMessage($this->lng->txt('err_check_input'));
862 }
863 if (($this->getCourseStart() && !$this->getCourseEnd()) ||
864 (!$this->getCourseStart() && $this->getCourseEnd()) ||
865 ($this->getCourseStart() && $this->getCourseEnd() && $this->getCourseStart()->get(IL_CAL_UNIX) > $this->getCourseEnd()->get(IL_CAL_UNIX))) {
866 $this->appendMessage($this->lng->txt("crs_course_period_not_valid"));
867 }
868
869 return strlen($this->getMessage()) > 0;
870 }
871
872 public function validateInfoSettings(): bool
873 {
874 $error = false;
875 if ($this->getContactEmail()) {
876 $emails = explode(",", $this->getContactEmail());
877
878 foreach ($emails as $email) {
879 $email = trim($email);
880 if (!ilUtil::is_email($email) && !ilObjUser::getUserIdByLogin($email)) {
881 $this->error->appendMessage($this->lng->txt('contact_email_not_valid') . " '" . $email . "'");
882 $error = true;
883 }
884 }
885 }
886 return !$error;
887 }
888
889 public function hasContactData(): bool
890 {
891 return strlen($this->getContactName()) || strlen($this->getContactResponsibility()) || strlen($this->getContactEmail()) || strlen($this->getContactPhone()) || strlen($this->getContactConsultation());
892 }
893
898 public function delete(): bool
899 {
900 // always call parent delete function first!!
901 if (!parent::delete()) {
902 return false;
903 }
904
905 // delete meta data
906 $this->deleteMetaData();
907
908 // put here course specific stuff
909
910 $this->__deleteSettings();
911
913
915
917
919
921
922 $this->app_event_handler->raise(
923 'components/ILIAS/Course',
924 'delete',
925 array('object' => $this,
926 'obj_id' => $this->getId(),
927 'appointments' => $this->prepareAppointments('delete')
928 )
929 );
930 return true;
931 }
932
936 public function update(): bool
937 {
938 $sorting = new ilContainerSortingSettings($this->getId());
939 $sorting->setSortMode($this->getOrderType());
940 $sorting->update();
941
942 $this->updateMetaData();
943 $this->updateSettings();
944 parent::update();
945
946 $this->app_event_handler->raise(
947 'components/ILIAS/Course',
948 'update',
949 array('object' => $this,
950 'obj_id' => $this->getId(),
951 'appointments' => $this->prepareAppointments('update')
952 )
953 );
954 return true;
955 }
956
959 public function updateSettings(): void
960 {
961 $query = "SELECT * FROM crs_settings WHERE obj_id = " . $this->db->quote($this->getId(), 'integer') . " ";
962 $res = $this->db->query($query);
963
964 if (!$res->numRows()) {
966 }
967
968 $query = "UPDATE crs_settings SET " .
969 'tutorial_support_block = ' . $this->db->quote($this->getTutorialSupportBlockSettingValue(), 'integer') . ", " .
970 "syllabus = " . $this->db->quote($this->getSyllabus(), 'text') . ", " .
971 "contact_name = " . $this->db->quote($this->getContactName(), 'text') . ", " .
972 "contact_responsibility = " . $this->db->quote($this->getContactResponsibility(), 'text') . ", " .
973 "contact_phone = " . $this->db->quote($this->getContactPhone(), 'text') . ", " .
974 "contact_email = " . $this->db->quote($this->getContactEmail(), 'text') . ", " .
975 "contact_consultation = " . $this->db->quote($this->getContactConsultation(), 'text') . ", " .
976 "activation_type = " . $this->db->quote(!$this->getOfflineStatus(), 'integer') . ", " .
977 "sub_limitation_type = " . $this->db->quote($this->getSubscriptionLimitationType(), 'integer') . ", " .
978 "sub_start = " . $this->db->quote($this->getSubscriptionStart(), 'integer') . ", " .
979 "sub_end = " . $this->db->quote($this->getSubscriptionEnd(), 'integer') . ", " .
980 "sub_type = " . $this->db->quote($this->getSubscriptionType(), 'integer') . ", " .
981 "sub_password = " . $this->db->quote($this->getSubscriptionPassword(), 'text') . ", " .
982 "sub_mem_limit = " . $this->db->quote((int) $this->isSubscriptionMembershipLimited(), 'integer') . ", " .
983 "sub_max_members = " . $this->db->quote($this->getSubscriptionMaxMembers(), 'integer') . ", " .
984 "sub_notify = " . $this->db->quote($this->getSubscriptionNotify(), 'integer') . ", " .
985 "view_mode = " . $this->db->quote($this->getViewMode(), 'integer') . ", " .
986 'timing_mode = ' . $this->db->quote($this->getTimingMode(), 'integer') . ', ' .
987 "abo = " . $this->db->quote($this->getAboStatus(), 'integer') . ", " .
988 "waiting_list = " . $this->db->quote($this->enabledWaitingList(), 'integer') . ", " .
989 "important = " . $this->db->quote($this->getImportantInformation(), 'text') . ", " .
990 'target_group = ' . $this->db->quote($this->getTargetGroup(), \ilDBConstants::T_TEXT) . ', ' .
991 "show_members = " . $this->db->quote($this->getShowMembers(), 'integer') . ", " .
992 "show_members_export = " . $this->db->quote($this->getShowMembersExport(), 'integer') . ", " .
993 "latitude = " . $this->db->quote($this->getLatitude(), 'text') . ", " .
994 "longitude = " . $this->db->quote($this->getLongitude(), 'text') . ", " .
995 "location_zoom = " . $this->db->quote($this->getLocationZoom(), 'integer') . ", " .
996 "enable_course_map = " . $this->db->quote((int) $this->getEnableCourseMap(), 'integer') . ", " .
997 'session_limit = ' . $this->db->quote($this->isSessionLimitEnabled(), 'integer') . ', ' .
998 'session_prev = ' . $this->db->quote($this->getNumberOfPreviousSessions(), 'integer') . ', ' .
999 'session_next = ' . $this->db->quote($this->getNumberOfNextSessions(), 'integer') . ', ' .
1000 'reg_ac_enabled = ' . $this->db->quote($this->isRegistrationAccessCodeEnabled(), 'integer') . ', ' .
1001 'reg_ac = ' . $this->db->quote($this->getRegistrationAccessCode(), 'text') . ', ' .
1002 'auto_notification = ' . $this->db->quote((int) $this->getAutoNotification(), 'integer') . ', ' .
1003 'status_dt = ' . $this->db->quote($this->getStatusDetermination(), ilDBConstants::T_INTEGER) . ', ' .
1004 'mail_members_type = ' . $this->db->quote($this->getMailToMembersType(), 'integer') . ', ' .
1005 'period_start = ' . $this->db->quote(
1008 ) . ', ' .
1009 'period_end = ' . $this->db->quote(
1012 ) . ', ' .
1013 'period_time_indication = ' . $this->db->quote(
1014 $this->getCourseStartTimeIndication() ? 1 : 0,
1016 ) . ', ' .
1017 'auto_wait = ' . $this->db->quote((int) $this->hasWaitingListAutoFill(), 'integer') . ', ' .
1018 'leave_end = ' . $this->db->quote(
1019 ($this->getCancellationEnd() && !$this->getCancellationEnd()->isNull()) ? $this->getCancellationEnd()->get(IL_CAL_UNIX) : null,
1020 'integer'
1021 ) . ', ' .
1022 'min_members = ' . $this->db->quote($this->getSubscriptionMinMembers(), 'integer') . ' ' .
1023 "WHERE obj_id = " . $this->db->quote($this->getId(), 'integer');
1024
1025 $res = $this->db->manipulate($query);
1026
1027 // moved activation to ilObjectActivation
1028 if ($this->ref_id ?? false) {
1029 ilObjectActivation::getItem($this->ref_id);
1030
1031 $item = new ilObjectActivation();
1032 if (!$this->getActivationStart() || !$this->getActivationEnd()) {
1033 $item->setTimingType(ilObjectActivation::TIMINGS_DEACTIVATED);
1034 } else {
1035 $item->setTimingType(ilObjectActivation::TIMINGS_ACTIVATION);
1036 $item->setTimingStart($this->getActivationStart());
1037 $item->setTimingEnd($this->getActivationEnd());
1038 $item->toggleVisible($this->getActivationVisibility());
1039 }
1040 $item->update($this->ref_id);
1041 }
1042 }
1043
1044 public function cloneSettings(ilObject $new_obj): void
1045 {
1046 $new_obj->setTutorialSupportBlockSettingValue($this->getTutorialSupportBlockSettingValue());
1047 $new_obj->setSyllabus($this->getSyllabus());
1048 $new_obj->setContactName($this->getContactName());
1049 $new_obj->setContactResponsibility($this->getContactResponsibility());
1050 $new_obj->setContactPhone($this->getContactPhone());
1051 $new_obj->setContactEmail($this->getContactEmail());
1052 $new_obj->setContactConsultation($this->getContactConsultation());
1053 $new_obj->setOfflineStatus($this->getOfflineStatus()); // #9914
1054 $new_obj->setActivationStart($this->getActivationStart());
1055 $new_obj->setActivationEnd($this->getActivationEnd());
1056 $new_obj->setActivationVisibility($this->getActivationVisibility());
1057 $new_obj->setSubscriptionLimitationType($this->getSubscriptionLimitationType());
1058 $new_obj->setSubscriptionStart($this->getSubscriptionStart());
1059 $new_obj->setSubscriptionEnd($this->getSubscriptionEnd());
1060 $new_obj->setSubscriptionType($this->getSubscriptionType());
1061 $new_obj->setSubscriptionPassword($this->getSubscriptionPassword());
1062 $new_obj->enableSubscriptionMembershipLimitation($this->isSubscriptionMembershipLimited());
1063 $new_obj->setSubscriptionMaxMembers($this->getSubscriptionMaxMembers());
1064 $new_obj->setViewMode($this->getViewMode());
1065 $new_obj->setTimingMode($this->getTimingMode());
1066 $new_obj->setOrderType($this->getOrderType());
1067 $new_obj->setAboStatus($this->getAboStatus());
1068 $new_obj->enableWaitingList($this->enabledWaitingList());
1069 $new_obj->setImportantInformation($this->getImportantInformation());
1070 $new_obj->setTargetGroup($this->getTargetGroup());
1071 $new_obj->setShowMembers($this->getShowMembers());
1072 // patch mem_exp
1073 $new_obj->setShowMembersExport($this->getShowMembersExport());
1074 // patch mem_exp
1075 $new_obj->enableSessionLimit($this->isSessionLimitEnabled());
1076 $new_obj->setNumberOfPreviousSessions($this->getNumberOfPreviousSessions());
1077 $new_obj->setNumberOfNextSessions($this->getNumberOfNextSessions());
1078 $new_obj->setAutoNotification($this->getAutoNotification());
1079 $new_obj->enableRegistrationAccessCode($this->isRegistrationAccessCodeEnabled());
1080 $new_obj->setRegistrationAccessCode(ilMembershipRegistrationCodeUtils::generateCode());
1081 $new_obj->setStatusDetermination($this->getStatusDetermination());
1082 $new_obj->setMailToMembersType($this->getMailToMembersType());
1083 $new_obj->setCoursePeriod(
1084 $this->getCourseStart(),
1085 $this->getCourseEnd()
1086 );
1087 $new_obj->setCancellationEnd($this->getCancellationEnd());
1088 $new_obj->setWaitingListAutoFill($this->hasWaitingListAutoFill());
1089 $new_obj->setSubscriptionMinMembers($this->getSubscriptionMinMembers());
1090
1091 // #10271
1092 $new_obj->setEnableCourseMap($this->getEnableCourseMap());
1093 $new_obj->setLatitude($this->getLatitude());
1094 $new_obj->setLongitude($this->getLongitude());
1095 $new_obj->setLocationZoom($this->getLocationZoom());
1096
1097 $new_obj->update();
1098 }
1099
1100 public function __createDefaultSettings(): void
1101 {
1103
1104 $query = "INSERT INTO crs_settings (obj_id,syllabus,contact_name,contact_responsibility," .
1105 "contact_phone,contact_email,contact_consultation," .
1106 "sub_limitation_type,sub_start,sub_end,sub_type,sub_password,sub_mem_limit," .
1107 "sub_max_members,sub_notify,view_mode,timing_mode,abo," .
1108 "latitude,longitude,location_zoom,enable_course_map,waiting_list,show_members,show_members_export, " .
1109 "session_limit,session_prev,session_next, reg_ac_enabled, reg_ac, auto_notification, status_dt, " .
1110 "mail_members_type, tutorial_support_block) " .
1111 "VALUES( " .
1112 $this->db->quote($this->getId(), 'integer') . ", " .
1113 $this->db->quote($this->getSyllabus(), 'text') . ", " .
1114 $this->db->quote($this->getContactName(), 'text') . ", " .
1115 $this->db->quote($this->getContactResponsibility(), 'text') . ", " .
1116 $this->db->quote($this->getContactPhone(), 'text') . ", " .
1117 $this->db->quote($this->getContactEmail(), 'text') . ", " .
1118 $this->db->quote($this->getContactConsultation(), 'text') . ", " .
1119 $this->db->quote(ilCourseConstants::IL_CRS_SUBSCRIPTION_DEACTIVATED, 'integer') . ", " .
1120 $this->db->quote($this->getSubscriptionStart(), 'integer') . ", " .
1121 $this->db->quote($this->getSubscriptionEnd(), 'integer') . ", " .
1122 $this->db->quote(ilCourseConstants::IL_CRS_SUBSCRIPTION_DIRECT, 'integer') . ", " .
1123 $this->db->quote($this->getSubscriptionPassword(), 'text') . ", " .
1124 "0, " .
1125 $this->db->quote($this->getSubscriptionMaxMembers(), 'integer') . ", " .
1126 "1, " .
1127 "0, " .
1128 $this->db->quote(ilCourseConstants::IL_CRS_VIEW_TIMING_ABSOLUTE, 'integer') . ', ' .
1129 $this->db->quote($this->getAboStatus(), 'integer') . ", " .
1130 $this->db->quote($this->getLatitude(), 'text') . ", " .
1131 $this->db->quote($this->getLongitude(), 'text') . ", " .
1132 $this->db->quote($this->getLocationZoom(), 'integer') . ", " .
1133 $this->db->quote($this->getEnableCourseMap(), 'integer') . ", " .
1134 #"objective_view = '0', ".
1135 "1, " .
1136 "1," .
1137 '0,' .
1138 $this->db->quote($this->isSessionLimitEnabled(), 'integer') . ', ' .
1139 $this->db->quote($this->getNumberOfPreviousSessions(), 'integer') . ', ' .
1140 $this->db->quote($this->getNumberOfPreviousSessions(), 'integer') . ', ' .
1141 $this->db->quote($this->isRegistrationAccessCodeEnabled(), 'integer') . ', ' .
1142 $this->db->quote($this->getRegistrationAccessCode(), 'text') . ', ' .
1143 $this->db->quote((int) $this->getAutoNotification(), 'integer') . ', ' .
1144 $this->db->quote($this->getStatusDetermination(), 'integer') . ', ' .
1145 $this->db->quote($this->getMailToMembersType(), 'integer') . ', ' .
1146 $this->db->quote($this->getTutorialSupportBlockSettingValue(), 'integer') . ' ' .
1147 ")";
1148
1149 $res = $this->db->manipulate($query);
1150 $this->__readSettings();
1151
1152 $sorting = new ilContainerSortingSettings($this->getId());
1153 $sorting->setSortMode(ilContainer::SORT_MANUAL);
1154 $sorting->update();
1155 }
1156
1157 public function __readSettings(): void
1158 {
1159 $query = "SELECT * FROM crs_settings WHERE obj_id = " . $this->db->quote($this->getId(), 'integer');
1160 $res = $this->db->query($query);
1161 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1162 $this->setTutorialSupportBlockSettingValue((int) $row->tutorial_support_block);
1163 $this->setSyllabus((string) $row->syllabus);
1164 $this->setTargetGroup($row->target_group);
1165 $this->setContactName((string) $row->contact_name);
1166 $this->setContactResponsibility((string) $row->contact_responsibility);
1167 $this->setContactPhone((string) $row->contact_phone);
1168 $this->setContactEmail((string) $row->contact_email);
1169 $this->setContactConsultation((string) $row->contact_consultation);
1170 $this->setSubscriptionLimitationType((int) $row->sub_limitation_type);
1171 $this->setSubscriptionStart((int) $row->sub_start);
1172 $this->setSubscriptionEnd((int) $row->sub_end);
1173 $this->setSubscriptionType((int) $row->sub_type);
1174 $this->setSubscriptionPassword((string) $row->sub_password);
1175 $this->enableSubscriptionMembershipLimitation((bool) $row->sub_mem_limit);
1176 $this->setSubscriptionMaxMembers((int) $row->sub_max_members);
1177 $this->setViewMode((int) $row->view_mode);
1178 $this->setTimingMode((int) $row->timing_mode);
1179 $this->setAboStatus((bool) $row->abo);
1180 $this->enableWaitingList((bool) $row->waiting_list);
1181 $this->setImportantInformation((string) $row->important);
1182 $this->setShowMembers((bool) $row->show_members);
1183
1184 if (\ilPrivacySettings::getInstance()->participantsListInCoursesEnabled()) {
1185 $this->setShowMembersExport((bool) $row->show_members_export);
1186 } else {
1187 $this->setShowMembersExport(false);
1188 }
1189 $this->setLatitude((string) $row->latitude);
1190 $this->setLongitude((string) $row->longitude);
1191 $this->setLocationZoom((int) $row->location_zoom);
1192 $this->setEnableCourseMap((bool) $row->enable_course_map);
1193 $this->enableSessionLimit((int) $row->session_limit);
1194 $this->setNumberOfPreviousSessions((int) $row->session_prev);
1195 $this->setNumberOfNextSessions((int) $row->session_next);
1196 $this->enableRegistrationAccessCode((bool) $row->reg_ac_enabled);
1197 $this->setRegistrationAccessCode((string) $row->reg_ac);
1198 $this->setAutoNotification((bool) $row->auto_notification);
1199 $this->setStatusDetermination((int) $row->status_dt);
1200 $this->setMailToMembersType((int) $row->mail_members_type);
1201
1202 if ($row->period_time_indication) {
1203 $this->setCoursePeriod(
1204 new \ilDateTime($row->period_start, IL_CAL_DATETIME, \ilTimeZone::UTC),
1205 new \ilDateTime($row->period_end, IL_CAL_DATETIME, \ilTimeZone::UTC)
1206 );
1207 } elseif (!is_null($row->period_start) && !is_null($row->period_end)) {
1208 $this->setCoursePeriod(
1209 new \ilDate($row->period_start, IL_CAL_DATE),
1210 new \ilDate($row->period_end, IL_CAL_DATE)
1211 );
1212 }
1213 $this->toggleCourseStartTimeIndication((bool) $row->period_time_indication);
1214 $this->setCancellationEnd($row->leave_end ? new ilDate($row->leave_end, IL_CAL_UNIX) : null);
1215 $this->setWaitingListAutoFill((bool) $row->auto_wait);
1216 $this->setSubscriptionMinMembers((int) $row->min_members);
1217 }
1218
1219 // moved activation to ilObjectActivation
1220 if ($this->ref_id ?? false) {
1221 $activation = ilObjectActivation::getItem($this->ref_id);
1222 switch ($activation["timing_type"]) {
1224 $this->setActivationStart((int) $activation["timing_start"]);
1225 $this->setActivationEnd((int) $activation["timing_end"]);
1226 $this->setActivationVisibility((bool) $activation["visible"]);
1227 break;
1228 }
1229 }
1230 }
1231
1232 public function initWaitingList(): void
1233 {
1234 if (!$this->waiting_list_obj instanceof ilCourseWaitingList) {
1235 $this->waiting_list_obj = new ilCourseWaitingList($this->getId());
1236 }
1237 }
1238
1239 protected function initCourseMemberObject(): void
1240 {
1241 $this->member_obj = ilCourseParticipant::_getInstanceByObjId($this->getId(), $this->user->getId());
1242 }
1243
1244 protected function initCourseMembersObject(): void
1245 {
1246 $this->members_obj = ilCourseParticipants::_getInstanceByObjId($this->getId());
1247 }
1248
1250 {
1251 if (!$this->member_obj instanceof ilCourseParticipant) {
1252 $this->initCourseMemberObject();
1253 }
1254 return $this->member_obj;
1255 }
1256
1258 {
1259 if (!$this->members_obj instanceof ilCourseParticipants) {
1260 $this->initCourseMembersObject();
1261 }
1262 return $this->members_obj;
1263 }
1264
1265
1266 // RBAC METHODS
1267 public function initDefaultRoles(): void
1268 {
1270 'il_crs_admin_' . $this->getRefId(),
1271 "Admin of crs obj_no." . $this->getId(),
1272 'il_crs_admin',
1273 $this->getRefId()
1274 );
1276 'il_crs_tutor_' . $this->getRefId(),
1277 "Tutor of crs obj_no." . $this->getId(),
1278 'il_crs_tutor',
1279 $this->getRefId()
1280 );
1282 'il_crs_member_' . $this->getRefId(),
1283 "Member of crs obj_no." . $this->getId(),
1284 'il_crs_member',
1285 $this->getRefId()
1286 );
1287 }
1288
1296 public function setParentRolePermissions(int $parent_ref_id): bool
1297 {
1298 $parent_roles = $this->rbac_review->getParentRoleIds($parent_ref_id);
1299 foreach ($parent_roles as $parent_role) {
1300 $this->rbac_admin->initIntersectionPermissions(
1301 $this->getRefId(),
1302 $parent_role['obj_id'],
1303 $parent_role['parent'],
1306 );
1307 }
1308 return true;
1309 }
1310
1312 {
1313 $q = "SELECT obj_id FROM object_data WHERE type='rolt' AND title='il_crs_non_member'";
1314 $res = $this->ilias->db->query($q);
1315 $row = $res->fetchRow(ilDBConstants::FETCHMODE_ASSOC);
1316 return (int) $row["obj_id"];
1317 }
1318
1319 public static function lookupCourseNonMemberTemplatesId(): int
1320 {
1321 global $DIC;
1322
1323 $ilDB = $DIC->database();
1324
1325 $query = 'SELECT obj_id FROM object_data WHERE type = ' . $ilDB->quote(
1326 'rolt',
1327 'text'
1328 ) . ' AND title = ' . $ilDB->quote('il_crs_non_member', 'text');
1329 $res = $ilDB->query($query);
1330 $row = $res->fetchRow(ilDBConstants::FETCHMODE_ASSOC);
1331 return (int) $row['obj_id'];
1332 }
1333
1340 public function getLocalCourseRoles($a_translate = false): array
1341 {
1342 if (empty($this->local_roles)) {
1343 $this->local_roles = array();
1344 $role_arr = $this->rbac_review->getRolesOfRoleFolder($this->getRefId());
1345
1346 foreach ($role_arr as $role_id) {
1347 if ($this->rbac_review->isAssignable($role_id, $this->getRefId())) {
1348 $role_Obj = ilObjectFactory::getInstanceByObjId($role_id);
1349 if ($a_translate) {
1350 $role_name = ilObjRole::_getTranslation($role_Obj->getTitle());
1351 } else {
1352 $role_name = $role_Obj->getTitle();
1353 }
1354 $this->local_roles[$role_name] = $role_Obj->getId();
1355 }
1356 }
1357 }
1358 return $this->local_roles;
1359 }
1360
1369 public function getDefaultCourseRoles(string $a_crs_id = ""): array
1370 {
1371 if (strlen($a_crs_id) > 0) {
1372 $crs_id = $a_crs_id;
1373 } else {
1374 $crs_id = $this->getRefId();
1375 }
1376
1377 $role_arr = $this->rbac_review->getRolesOfRoleFolder($crs_id);
1378
1379 $arr_crsDefaultRoles = [];
1380 foreach ($role_arr as $role_id) {
1381 $role_Obj = &$this->ilias->obj_factory->getInstanceByObjId($role_id);
1382
1383 $crs_Member = "il_crs_member_" . $crs_id;
1384 $crs_Admin = "il_crs_admin_" . $crs_id;
1385 $crs_Tutor = "il_crs_tutor_" . $crs_id;
1386
1387 if (strcmp($role_Obj->getTitle(), $crs_Member) == 0) {
1388 $arr_crsDefaultRoles["crs_member_role"] = $role_Obj->getId();
1389 }
1390
1391 if (strcmp($role_Obj->getTitle(), $crs_Admin) == 0) {
1392 $arr_crsDefaultRoles["crs_admin_role"] = $role_Obj->getId();
1393 }
1394
1395 if (strcmp($role_Obj->getTitle(), $crs_Tutor) == 0) {
1396 $arr_crsDefaultRoles["crs_tutor_role"] = $role_Obj->getId();
1397 }
1398 }
1399
1400 return $arr_crsDefaultRoles;
1401 }
1402
1406 public function __getLocalRoles(): array
1407 {
1408 return $this->rbac_review->getRolesOfRoleFolder($this->getRefId(), false);
1409 }
1410
1411 public function __deleteSettings(): void
1412 {
1413 $query = "DELETE FROM crs_settings " .
1414 "WHERE obj_id = " . $this->db->quote($this->getId(), 'integer') . " ";
1415 $this->db->manipulate($query);
1416 }
1417
1418 public function getDefaultMemberRole(): int
1419 {
1420 $local_roles = $this->__getLocalRoles();
1421 foreach ($local_roles as $role_id) {
1422 $title = ilObject::_lookupTitle($role_id);
1423 if (substr($title, 0, 8) == 'il_crs_m') {
1424 return $role_id;
1425 }
1426 }
1427 return 0;
1428 }
1429
1430 public function getDefaultTutorRole(): int
1431 {
1432 $local_roles = $this->__getLocalRoles();
1433 foreach ($local_roles as $role_id) {
1434 if ($tmp_role = ilObjectFactory::getInstanceByObjId($role_id, false)) {
1435 if (!strcmp($tmp_role->getTitle(), "il_crs_tutor_" . $this->getRefId())) {
1436 return $role_id;
1437 }
1438 }
1439 }
1440 return 0;
1441 }
1442
1443 public function getDefaultAdminRole(): int
1444 {
1445 $local_roles = $this->__getLocalRoles();
1446 foreach ($local_roles as $role_id) {
1447 if ($tmp_role = ilObjectFactory::getInstanceByObjId($role_id, false)) {
1448 if (!strcmp($tmp_role->getTitle(), "il_crs_admin_" . $this->getRefId())) {
1449 return $role_id;
1450 }
1451 }
1452 }
1453 return 0;
1454 }
1455
1456 public static function _deleteUser(int $a_usr_id): void
1457 {
1461 }
1462
1463 protected function doMDUpdateListener(string $a_element): void
1464 {
1465 switch ($a_element) {
1466 case 'General':
1467 // Update ecs content
1468 $ecs = new ilECSCourseSettings($this);
1469 $ecs->handleContentUpdate();
1470 break;
1471 }
1472 }
1473
1474 public function addAdditionalSubItemInformation(array &$object): void
1475 {
1477 }
1478
1482 protected function prepareAppointments(string $a_mode = 'create'): array
1483 {
1484 switch ($a_mode) {
1485 case 'create':
1486 case 'update':
1487 $apps = [];
1488 if (!$this->getActivationUnlimitedStatus() && !$this->getOfflineStatus()) {
1489 $app = new ilCalendarAppointmentTemplate(self::CAL_ACTIVATION_START);
1490 $app->setTitle($this->getTitle());
1491 $app->setSubtitle('crs_cal_activation_start');
1492 $app->setTranslationType(ilCalendarEntry::TRANSLATION_SYSTEM);
1493 $app->setDescription($this->getLongDescription());
1494 $app->setStart(new ilDateTime($this->getActivationStart(), IL_CAL_UNIX));
1495 $apps[] = $app;
1496
1497 $app = new ilCalendarAppointmentTemplate(self::CAL_ACTIVATION_END);
1498 $app->setTitle($this->getTitle());
1499 $app->setSubtitle('crs_cal_activation_end');
1500 $app->setTranslationType(ilCalendarEntry::TRANSLATION_SYSTEM);
1501 $app->setDescription($this->getLongDescription());
1502 $app->setStart(new ilDateTime($this->getActivationEnd(), IL_CAL_UNIX));
1503 $apps[] = $app;
1504 }
1506 $app = new ilCalendarAppointmentTemplate(self::CAL_REG_START);
1507 $app->setTitle($this->getTitle());
1508 $app->setSubtitle('crs_cal_reg_start');
1509 $app->setTranslationType(ilCalendarEntry::TRANSLATION_SYSTEM);
1510 $app->setDescription($this->getLongDescription());
1511 $app->setStart(new ilDateTime($this->getSubscriptionStart(), IL_CAL_UNIX));
1512 $apps[] = $app;
1513
1514 $app = new ilCalendarAppointmentTemplate(self::CAL_REG_END);
1515 $app->setTitle($this->getTitle());
1516 $app->setSubtitle('crs_cal_reg_end');
1517 $app->setTranslationType(ilCalendarEntry::TRANSLATION_SYSTEM);
1518 $app->setDescription($this->getLongDescription());
1519 $app->setStart(new ilDateTime($this->getSubscriptionEnd(), IL_CAL_UNIX));
1520 $apps[] = $app;
1521 }
1522 if ($this->getCourseStart() && $this->getCourseEnd()) {
1523 $app = new ilCalendarAppointmentTemplate(self::CAL_COURSE_START);
1524 $app->setTitle($this->getTitle());
1525 $app->setSubtitle('crs_cal_start');
1526 $app->setTranslationType(ilCalendarEntry::TRANSLATION_SYSTEM);
1527 $app->setDescription($this->getLongDescription());
1528 $app->setStart($this->getCourseStart());
1529 $app->setFullday(!$this->getCourseStartTimeIndication());
1530 $apps[] = $app;
1531
1532 $app = new ilCalendarAppointmentTemplate(self::CAL_COURSE_END);
1533 $app->setTitle($this->getTitle());
1534 $app->setSubtitle('crs_cal_end');
1535 $app->setTranslationType(ilCalendarEntry::TRANSLATION_SYSTEM);
1536 $app->setDescription($this->getLongDescription());
1537 $app->setStart($this->getCourseEnd());
1538 $app->setFullday(!$this->getCourseStartTimeIndication());
1539 $apps[] = $app;
1540 }
1541 if (
1543 ) {
1545 foreach ($active as $null => $item) {
1546 if ($item['timing_type'] == ilObjectActivation::TIMINGS_PRESETTING) {
1547 // create calendar entry for fixed types
1548 $app = new ilCalendarAppointmentTemplate(self::CAL_COURSE_TIMING_START);
1549 $app->setContextInfo($item['ref_id']);
1550 $app->setTitle($item['title']);
1551 $app->setSubtitle('cal_crs_timing_start');
1552 $app->setTranslationType(ilCalendarEntry::TRANSLATION_SYSTEM);
1553 $app->setStart(new ilDate($item['suggestion_start'], IL_CAL_UNIX));
1554 $app->setFullday(true);
1555 $apps[] = $app;
1556
1557 $app = new ilCalendarAppointmentTemplate(self::CAL_COURSE_TIMING_END);
1558 $app->setContextInfo($item['ref_id']);
1559 $app->setTitle($item['title']);
1560 $app->setSubtitle('cal_crs_timing_end');
1561 $app->setTranslationType(ilCalendarEntry::TRANSLATION_SYSTEM);
1562 $app->setStart(new ilDate($item['suggestion_end'], IL_CAL_UNIX));
1563 $app->setFullday(true);
1564 $apps[] = $app;
1565 }
1566 }
1567 }
1568 return $apps;
1569
1570 case 'delete':
1571 // Nothing to do: The category and all assigned appointments will be deleted.
1572 return array();
1573 }
1574 return [];
1575 }
1576
1581 public static function lookupObjectsByCode(string $a_code): array
1582 {
1583 global $DIC;
1584
1585 $ilDB = $DIC->database();
1586
1587 $query = "SELECT obj_id FROM crs_settings " .
1588 "WHERE reg_ac_enabled = " . $ilDB->quote(1, 'integer') . " " .
1589 "AND reg_ac = " . $ilDB->quote($a_code, 'text');
1590 $res = $ilDB->query($query);
1591
1592 $obj_ids = array();
1593 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1594 $obj_ids[] = (int) $row->obj_id;
1595 }
1596 return $obj_ids;
1597 }
1598
1603 public function register(
1604 int $a_user_id,
1605 int $a_role = ilCourseConstants::CRS_MEMBER,
1606 bool $a_force_registration = false
1607 ): void {
1608 if ($this->getMembersObject()->isAssigned($a_user_id)) {
1609 return;
1610 }
1611
1612 if (!$a_force_registration) {
1613 // offline
1614 if (ilObjCourseAccess::_isOffline($this->getId())) {
1616 "Can't register to course, course is offline.",
1618 );
1619 }
1620 // activation
1621 if (!ilObjCourseAccess::_isActivated($this->getId())) {
1623 "Can't register to course, course is not activated.",
1625 );
1626 }
1627
1631 'Cant registrate to course ' . $this->getId() .
1632 ', course subscription is deactivated.',
1634 );
1635 }
1636 }
1637
1638 // Time Limitation
1640 if (!$this->inSubscriptionTime()) {
1642 'Cant registrate to course ' . $this->getId() .
1643 ', course is out of registration time.',
1645 );
1646 }
1647 }
1648
1649 // Max members
1650 if ($this->isSubscriptionMembershipLimited()) {
1651 $free = max(0, $this->getSubscriptionMaxMembers() - $this->getMembersObject()->getCountMembers());
1652 $waiting_list = new ilCourseWaitingList($this->getId());
1653 if ($this->enabledWaitingList() && (!$free || $waiting_list->getCountUsers())) {
1654 $waiting_list->addToList($a_user_id);
1655 $this->lng->loadLanguageModule("crs");
1656 $info = sprintf(
1657 $this->lng->txt('crs_added_to_list'),
1658 $waiting_list->getPosition($a_user_id)
1659 );
1660 $participants = ilCourseParticipants::_getInstanceByObjId($this->getId());
1661 $participants->sendNotification(
1663 $a_user_id
1664 );
1665
1667 $info,
1669 );
1670 }
1671
1672 if (!$this->enabledWaitingList() && !$free) {
1673 throw new ilMembershipRegistrationException('Cant registrate to course ' . $this->getId() .
1674 ', membership is limited.', ilMembershipRegistrationException::OBJECT_IS_FULL);
1675 }
1676 }
1677 }
1678
1679 $this->getMembersObject()->add($a_user_id, $a_role);
1683 }
1684
1689 public function getAutoNotification(): bool
1690 {
1692 }
1693
1698 public function setAutoNotification(bool $value): void
1699 {
1700 $this->auto_notification = $value;
1701 }
1702
1706 public function setStatusDetermination(int $a_value): void
1707 {
1708 $a_value = $a_value;
1709
1710 // #13905
1711 if ($a_value == self::STATUS_DETERMINATION_LP) {
1714 }
1715 }
1716
1717 $this->status_dt = $a_value;
1718 }
1719
1723 public function getStatusDetermination(): int
1724 {
1725 return $this->status_dt;
1726 }
1727
1728 public function syncMembersStatusWithLP(): void
1729 {
1730 foreach ($this->getMembersObject()->getParticipants() as $user_id) {
1731 // #15529 - force raise on sync
1732 ilLPStatusWrapper::_updateStatus($this->getId(), $user_id, null, false, true);
1733 }
1734 }
1735
1740 public function checkLPStatusSync(int $a_member_id): void
1741 {
1742 // #11113
1745 // #13811 - we need to suppress creation if status entry
1746 $has_completed = (ilLPStatus::_lookupStatus(
1747 $this->getId(),
1748 $a_member_id,
1749 false
1751 $this->getMembersObject()->updatePassed($a_member_id, $has_completed, false, true);
1752 }
1753 }
1754
1755 public function getOrderType(): int
1756 {
1757 if ($this->enabledObjectiveView()) {
1759 }
1760 return parent::getOrderType();
1761 }
1762
1766 public function handleAutoFill(): void
1767 {
1768 if (
1769 !$this->enabledWaitingList() || !$this->hasWaitingListAutoFill()
1770 ) {
1771 $this->course_logger->debug('Waiting list or auto fill disabled.');
1772 return;
1773 }
1774
1775 $max = $this->getSubscriptionMaxMembers();
1777
1778 $this->course_logger->debug('Max members: ' . $max);
1779 $this->course_logger->debug('Current members: ' . $now);
1780
1781 if ($max <= $now) {
1782 return;
1783 }
1784
1785 // see assignFromWaitingListObject()
1786 $waiting_list = new ilCourseWaitingList($this->getId());
1787
1788 foreach ($waiting_list->getUserIds() as $user_id) {
1789 if (!$tmp_obj = ilObjectFactory::getInstanceByObjId($user_id, false)) {
1790 $this->course_logger->warning('Cannot create user instance for id: ' . $user_id);
1791 continue;
1792 }
1793 if ($this->getMembersObject()->isAssigned($user_id)) {
1794 $this->course_logger->warning('User is already assigned to course. uid: ' . $user_id . ' course_id: ' . $this->getRefId());
1795 continue;
1796 }
1797 $this->getMembersObject()->add($user_id, ilParticipants::IL_CRS_MEMBER);
1798 $this->getMembersObject()->sendNotification(ilCourseMembershipMailNotification::TYPE_ADMISSION_MEMBER, $user_id, true);
1799 $waiting_list->removeFromList($user_id);
1800 $this->checkLPStatusSync($user_id);
1801
1802 $this->course_logger->info('Assigned user from waiting list to course: ' . $this->getTitle());
1803 $now++;
1804 if ($now >= $max) {
1805 break;
1806 }
1807 }
1808 }
1809
1810 public static function mayLeave(int $a_course_id, int $a_user_id = 0, &$a_date = null): bool
1811 {
1812 global $DIC;
1813
1814 $ilUser = $DIC['ilUser'];
1815 $ilDB = $DIC['ilDB'];
1816
1817 if (!$a_user_id) {
1818 $a_user_id = $ilUser->getId();
1819 }
1820
1821 $set = $ilDB->query("SELECT leave_end" .
1822 " FROM crs_settings" .
1823 " WHERE obj_id = " . $ilDB->quote($a_course_id, "integer"));
1824 $row = $ilDB->fetchAssoc($set);
1825 if ($row && $row["leave_end"]) {
1826 // timestamp to date
1827 $limit = date("Ymd", $row["leave_end"]);
1828 if ($limit < date("Ymd")) {
1829 $a_date = new ilDate(date("Y-m-d", $row["leave_end"]), IL_CAL_DATE);
1830 return false;
1831 }
1832 }
1833 return true;
1834 }
1835
1836 public static function findCoursesWithNotEnoughMembers(): array
1837 {
1838 $ilDB = $GLOBALS['DIC']->database();
1839 $tree = $GLOBALS['DIC']->repositoryTree();
1840
1841 $res = array();
1842
1843 $before = new ilDateTime(time(), IL_CAL_UNIX);
1844 $now = $before->get(IL_CAL_UNIX);
1845 $now_dt = $before->get(IL_CAL_DATETIME, '', ilTimeZone::UTC);
1846
1847 $set = $ilDB->query("SELECT obj_id, min_members" .
1848 " FROM crs_settings" .
1849 " WHERE min_members > " . $ilDB->quote(0, "integer") .
1850 " AND sub_mem_limit = " . $ilDB->quote(1, "integer") . // #17206
1851 " AND ((leave_end IS NOT NULL" .
1852 " AND leave_end < " . $ilDB->quote($now, "text") . ")" .
1853 " OR (leave_end IS NULL" .
1854 " AND sub_end IS NOT NULL" .
1855 " AND sub_end < " . $ilDB->quote($now, "text") . "))" .
1856 " AND (period_start IS NULL OR period_start > " . $ilDB->quote($now_dt, ilDBConstants::T_TEXT) . ")");
1857 while ($row = $ilDB->fetchAssoc($set)) {
1858 $refs = ilObject::_getAllReferences((int) $row['obj_id']);
1859 $ref = end($refs);
1860
1861 if ($tree->isDeleted($ref)) {
1862 continue;
1863 }
1864
1865 $part = new ilCourseParticipants((int) $row["obj_id"]);
1866 $reci = $part->getNotificationRecipients();
1867 if ($reci !== []) {
1868 $missing = (int) $row["min_members"] - $part->getCountMembers();
1869 if ($missing > 0) {
1870 $res[(int) $row["obj_id"]] = array($missing, $reci);
1871 }
1872 }
1873 }
1874
1875 return $res;
1876 }
1877} //END class.ilObjCourse
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
const IL_CAL_DATE
const IL_CAL_UNIX
const IL_CAL_DATETIME
error(string $a_errmsg)
static getInstancesByParentId(int $a_parent_id, ?array $a_filter=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Apointment templates are used for automatic generated apointments.
static convertDateToUtcDBTimestamp(?\ilDateTime $date=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilContainer.
setOrderType(int $a_value)
static _getInstance(int $a_copy_id)
static _clone(int $a_source_id, int $a_target_id)
static _deleteByCourse(int $a_course_id)
static _cloneFiles(int $a_source_id, int $a_target_id)
static _deleteUser(int $a_usr_id)
class ilcourseobjective
static _deleteAll(int $course_id)
static _getInstanceByObjId(int $a_obj_id, int $a_usr_id)
static _getInstanceByObjId(int $a_obj_id)
@classDescription Date and time handling
Class for single dates.
Class ilECSCourseSettings.
static checkForumsExistsInsert(int $ref_id, int $user_id)
static cloneSettings(int $a_copy_id, int $a_container_id, int $a_new_container_id)
static deleteResultsForUser(int $a_user_id)
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
const LP_STATUS_COMPLETED_NUM
static _lookupStatus(int $a_obj_id, int $a_user_id, bool $a_create=true)
Lookup status.
Component logger with individual log levels by component id.
static generateCode()
Generate new registration key.
static _registrationEnabled(int $a_obj_id)
static _isActivated(int $a_obj_id, ?bool &$a_visible_flag=null, bool $a_mind_member_view=true)
static _isOffline(int $obj_id)
Type-specific implementation of general status, has to be overwritten if object type does not support...
static _deleteAll(int $a_course_id)
static _getGroupings(int $a_course_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static lookupCourseNonMemberTemplatesId()
static _lookupAboStatus(int $a_id)
ilCourseWaitingList $waiting_list_obj
setSubscriptionMaxMembers(int $a_value)
setLongitude(string $a_longitude)
static _deleteUser(int $a_usr_id)
static _lookupViewMode(int $a_id)
const int CAL_REG_END
__construct(int $a_id=0, bool $a_call_by_reference=true)
checkLPStatusSync(int $a_member_id)
sync course status from lp as lp data is not deleted on course exit new members may already have lp c...
bool $reg_access_code_enabled
prepareAppointments(string $a_mode='create')
Prepare calendar appointments.
ilCourseParticipants $members_obj
enableSubscriptionMembershipLimitation(bool $a_status)
setTargetGroup(?string $a_tg)
setSubscriptionLimitationType(int $a_type)
setNumberOfPreviousSessions(int $a_num)
getTutorialSupportBlockSettingValue()
bool $auto_fill_from_waiting
setContactEmail(string $a_value)
static lookupObjectsByCode(string $a_code)
setCoursePeriod(?ilDateTime $start=null, ?ilDateTime $end=null)
appendMessage(string $a_message)
ilDateTime $crs_start
static lookupShowMembersEnabled(int $a_obj_id)
setContactPhone(string $a_value)
setParentRolePermissions(int $parent_ref_id)
This method is called before "initDefaultRoles".
string $reg_access_code
ilLogger $course_logger
bool $activation_visibility
static lookupTutorialBlockSettingEabled(int $a_obj_id)
setImportantInformation(string $a_info)
getDefaultCourseRoles(string $a_crs_id="")
get default course roles, returns the defaultlike create roles il_crs_tutor, il_crs_admin and il_crs_...
setShowMembersExport(bool $a_mem_export)
cloneObject(int $target_id, int $copy_id=0, bool $omit_tree=false)
Clone course (no member data)
handleAutoFill()
Handle course auto fill.
update()
@inheritDoc
enableSessionLimit(int $a_status)
initDefaultRoles()
init default roles settings Purpose of this function is to create a local role folder and local roles...
cloneSettings(ilObject $new_obj)
const int STATUS_DETERMINATION_MANUAL
setSubscriptionEnd(int $a_value)
setActivationVisibility(bool $a_value)
cloneDependencies(int $target_id, int $copy_id)
@inheritDoc
getLocalCourseRoles($a_translate=false)
get ALL local roles of course, also those created and defined afterwards only fetch data once from da...
setLatitude(string $a_latitude)
int $subscription_max_members
enableRegistrationAccessCode(bool $a_status)
bool $subscription_membership_limitation
static _isSubscriptionNotificationEnabled(int $a_course_id)
setViewMode(int $a_mode)
setCourseStart(?ilDateTime $a_value=null)
static lookupTimingMode(int $a_obj_id)
setTutorialSupportBlockSettingValue(int $value)
setTimingMode(int $a_mode)
setContactConsultation(string $a_value)
doMDUpdateListener(string $a_element)
static findCoursesWithNotEnoughMembers()
setSubscriptionPassword(string $a_value)
setContactName(string $a_cn)
const int CAL_REG_START
setNumberOfNextSessions(int $a_num)
const int CAL_COURSE_TIMING_START
setMailToMembersType(int $a_type)
const int STATUS_DETERMINATION_LP
static _registrationEnabled(int $a_obj_id)
Registration enabled? Method is in Access class, since it is needed by Access/ListGUI.
string $contact_responsibility
toggleCourseStartTimeIndication(bool $time_indication)
int $subscription_limitation_type
addAdditionalSubItemInformation(array &$object)
Add additional information to sub item, e.g.
setCourseEnd(?ilDateTime $a_value=null)
setActivationEnd(int $a_value)
const int CAL_ACTIVATION_START
static _isActivated(int $a_obj_id)
Is activated.
setSubscriptionStart(int $a_value)
setActivationStart(int $a_value)
setSubscriptionType(int $a_value)
setSyllabus(string $a_syllabus)
setMessage(string $a_message)
int $tutorial_support_block_setting_value
create()
note: title, description and type should be set when this function is called
bool $crs_start_time_indication
setAboStatus(bool $a_status)
getStatusDetermination()
Get status determination mode.
ilDateTime $crs_end
static mayLeave(int $a_course_id, int $a_user_id=0, &$a_date=null)
setShowMembers(bool $a_status)
setEnableCourseMap(bool $a_enablemap)
bool $course_start_time_indication
string $contact_consultation
ilCourseParticipant $member_obj
const int CAL_COURSE_TIMING_END
setStatusDetermination(int $a_value)
Set status determination mode.
setLocationZoom(int $a_locationzoom)
const int CAL_COURSE_START
setRegistrationAccessCode(string $a_code)
setCancellationEnd(?ilDate $a_value=null)
string $subscription_password
setWaitingListAutoFill(bool $a_value)
const int CAL_ACTIVATION_END
const int CAL_COURSE_END
enableWaitingList(bool $a_status)
setContactResponsibility(string $a_value)
cloneAutoGeneratedRoles(ilObject $new_obj)
Clone automatic genrated roles (permissions and template permissions)
setSubscriptionMinMembers(int $a_value)
getAutoNotification()
Returns automatic notification status from $this->auto_notification.
setAutoNotification(bool $value)
Sets automatic notification status in $this->auto_notification, using given $status.
static createDefaultRole(string $a_title, string $a_description, string $a_tpl_name, int $a_ref_id)
static _getTranslation(string $a_role_title)
static getUserIdByLogin(string $a_login)
Class ilObjectActivation.
static cloneDependencies(int $ref_id, int $target_id, int $copy_id)
static getTimingsItems(int $container_ref_id)
Get (sub) item data for timings view (no session material, no side blocks)
static getItem(int $ref_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.
string $title
cloneMetaData(ilObject $target_obj)
Copy meta data.
static _getAllReferences(int $id)
get all reference ids for object ID
ilTree $tree
ilErrorHandling $error
getLongDescription()
get object long description (stored in object_description)
setOfflineStatus(bool $status)
static _lookupObjId(int $ref_id)
static _lookupTitle(int $obj_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.
static _deleteUser(int $a_usr_id)
Delete user data.
isDeleted(int $a_node_id)
This is a wrapper for isSaved() with a more useful name.
static is_email(string $a_email, ?ilMailRfc822AddressParserFactory $mailAddressParserFactory=null)
This preg-based function checks whether an e-mail address is formally valid.
const ROLE_FOLDER_ID
Definition: constants.php:34
$info
Definition: entry_point.php:21
Interface for all objects that offer registration with access codes.
$res
Definition: ltiservices.php:69
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Class ilObjForumAdministration.
global $DIC
Definition: shib_login.php:26
$q
Definition: shib_logout.php:23
$GLOBALS["DIC"]
Definition: wac.php:54