ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilObjCourseGrouping.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=0);
26{
27 protected static array $assignedObjects = array();
28
29 private int $id = 0;
30 private int $ref_id = 0;
31 private int $obj_id = 0;
32 private string $container_type = '';
33 private string $type = '';
34 private string $title = '';
35 private string $description = '';
36 private string $unique_field = '';
37
39 protected ilDBInterface $db;
40 protected ilTree $tree;
41 protected ilObjUser $user;
44
45 public function __construct(int $a_id = 0)
46 {
47 global $DIC;
48
49 $this->logger = $DIC->logger()->crs();
50 $this->setType('crsg');
51 $this->db = $DIC->database();
52 $this->tree = $DIC->repositoryTree();
53 $this->user = $DIC->user();
54 $this->objectDataCache = $DIC['ilObjDataCache'];
55 $this->access = $DIC->access();
56 $this->setId($a_id);
57
58 if ($a_id) {
59 $this->read();
60 }
61 }
62
63 public function setId(int $a_id): void
64 {
65 $this->id = $a_id;
66 }
67
68 public function getId(): int
69 {
70 return $this->id;
71 }
72
73 public function setContainerRefId(int $a_ref_id): void
74 {
75 $this->ref_id = $a_ref_id;
76 }
77
78 public function getContainerRefId(): int
79 {
80 return $this->ref_id;
81 }
82
83 public function setContainerObjId(int $a_obj_id): void
84 {
85 $this->obj_id = $a_obj_id;
86 }
87
88 public function getContainerObjId(): int
89 {
90 return $this->obj_id;
91 }
92
93 public function getContainerType(): string
94 {
96 }
97
98 public function setContainerType(string $a_type): void
99 {
100 $this->container_type = $a_type;
101 }
102
103 public function setType(string $a_type): void
104 {
105 $this->type = $a_type;
106 }
107
108 public function getType(): string
109 {
110 return $this->type;
111 }
112
113 public function setTitle(string $a_title): void
114 {
115 $this->title = $a_title;
116 }
117
118 public function getTitle(): string
119 {
120 return $this->title;
121 }
122
123 public function setDescription(string $a_desc): void
124 {
125 $this->description = $a_desc;
126 }
127
128 public function getDescription(): string
129 {
130 return $this->description;
131 }
132
133 public function setUniqueField(string $a_uni): void
134 {
135 $this->unique_field = $a_uni;
136 }
137
138 public function getUniqueField(): string
139 {
140 return $this->unique_field;
141 }
142
143 public function getCountAssignedItems(): int
144 {
145 return count($this->getAssignedItems());
146 }
147
148 public function getAssignedItems(): array
149 {
150 $condition_data = ilConditionHandler::_getPersistedConditionsOfTrigger($this->getType(), $this->getId());
151 $conditions = array();
152 foreach ($condition_data as $condition) {
153 if ($this->tree->isDeleted($condition['target_ref_id'])) {
154 continue;
155 }
156 $conditions[] = $condition;
157 }
158 return count($conditions) ? $conditions : array();
159 }
160
161 public function delete(): void
162 {
163 if ($this->getId() && $this->getType() === 'crsg') {
164 $query = "DELETE FROM object_data WHERE obj_id = " . $this->db->quote($this->getId(), 'integer') . " ";
165 $res = $this->db->manipulate($query);
166
167 $query = "DELETE FROM crs_groupings " .
168 "WHERE crs_grp_id = " . $this->db->quote($this->getId(), 'integer') . " ";
169 $res = $this->db->manipulate($query);
170
171 // Delete conditions
172 $condh = new ilConditionHandler();
173 $condh->deleteByObjId($this->getId());
174 }
175 }
176
177 public function create(int $a_course_ref_id, int $a_course_id): void
178 {
179 // INSERT IN object_data
180 $this->setId($this->db->nextId("object_data"));
181 $query = "INSERT INTO object_data " .
182 "(obj_id, type,title,description,owner,create_date,last_update) " .
183 "VALUES " .
184 "(" .
185 $this->db->quote($this->getId(), "integer") . "," .
186 $this->db->quote($this->type, "text") . "," .
187 $this->db->quote($this->getTitle(), "text") . "," .
188 $this->db->quote($this->getDescription(), "text") . "," .
189 $this->db->quote($this->user->getId(), "integer") . "," .
190 $this->db->now() . "," .
191 $this->db->now() .
192 ')';
193
194 $this->db->manipulate($query);
195
196 // INSERT in crs_groupings
197 $query = "INSERT INTO crs_groupings (crs_grp_id,crs_ref_id,crs_id,unique_field) " .
198 "VALUES (" .
199 $this->db->quote($this->getId(), 'integer') . ", " .
200 $this->db->quote($a_course_ref_id, 'integer') . ", " .
201 $this->db->quote($a_course_id, 'integer') . ", " .
202 $this->db->quote($this->getUniqueField(), 'text') . " " .
203 ")";
204 $res = $this->db->manipulate($query);
205 }
206
207 public function update(): void
208 {
209 if ($this->getId() && $this->getType() === 'crsg') {
210 // UPDATe object_data
211 $query = "UPDATE object_data " .
212 "SET title = " . $this->db->quote($this->getTitle(), 'text') . ", " .
213 "description = " . $this->db->quote($this->getDescription(), 'text') . " " .
214 "WHERE obj_id = " . $this->db->quote($this->getId(), 'integer') . " " .
215 "AND type = " . $this->db->quote($this->getType(), 'text') . " ";
216 $res = $this->db->manipulate($query);
217
218 // UPDATE crs_groupings
219 $query = "UPDATE crs_groupings " .
220 "SET unique_field = " . $this->db->quote($this->getUniqueField(), 'text') . " " .
221 "WHERE crs_grp_id = " . $this->db->quote($this->getId(), 'integer') . " ";
222 $res = $this->db->manipulate($query);
223
224 // UPDATE conditions
225 $query = "UPDATE conditions " .
226 "SET value = " . $this->db->quote($this->getUniqueField(), 'text') . " " .
227 "WHERE trigger_obj_id = " . $this->db->quote($this->getId(), 'integer') . " " .
228 "AND trigger_type = 'crsg'";
229 $res = $this->db->manipulate($query);
230 }
231 }
232
233 public function isAssigned(int $a_course_id): bool
234 {
235 foreach ($this->getAssignedItems() as $condition_data) {
236 if ($a_course_id == $condition_data['target_obj_id']) {
237 return true;
238 }
239 }
240 return false;
241 }
242
243 public function read(): void
244 {
245 $query = "SELECT * FROM object_data " .
246 "WHERE obj_id = " . $this->db->quote($this->getId(), 'integer') . " ";
247
248 $res = $this->db->query($query);
249 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
250 $this->setTitle((string) $row->title);
251 $this->setDescription((string) $row->description);
252 }
253
254 $query = "SELECT * FROM crs_groupings " .
255 "WHERE crs_grp_id = " . $this->db->quote($this->getId(), 'integer') . " ";
256 $res = $this->db->query($query);
257
258 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
259 $this->setUniqueField((string) $row->unique_field);
260 $this->setContainerRefId((int) $row->crs_ref_id);
261 $this->setContainerObjId((int) $row->crs_id);
262 $this->setContainerType($this->objectDataCache->lookupType($this->getContainerObjId()));
263 }
264 }
265
266 public function _checkAccess(int $grouping_id): bool
267 {
268 $tmp_grouping_obj = new ilObjCourseGrouping($grouping_id);
269
270 $found_invisible = false;
271 foreach ($tmp_grouping_obj->getAssignedItems() as $condition) {
272 if (!$this->access->checkAccess('write', '', $condition['target_ref_id'])) {
273 $found_invisible = true;
274 break;
275 }
276 }
277 return !$found_invisible;
278 }
279
285 public static function _getVisibleGroupings(int $a_obj_id): array
286 {
287 global $DIC;
288
289 $ilObjDataCache = $DIC['ilObjDataCache'];
290 $ilAccess = $DIC['ilAccess'];
291 $ilDB = $DIC['ilDB'];
292
293 $container_type = $ilObjDataCache->lookupType($a_obj_id) == 'grp' ? 'grp' : 'crs';
294
295 // First get all groupings
296 $query = "SELECT * FROM object_data WHERE type = 'crsg' ORDER BY title";
297 $res = $ilDB->query($query);
298 $groupings = array();
299 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
300 $groupings[] = (int) $row->obj_id;
301 }
302
303 //check access
304 $visible_groupings = [];
305 foreach ($groupings as $grouping_id) {
306 $tmp_grouping_obj = new ilObjCourseGrouping($grouping_id);
307
308 // Check container type
309 if ($tmp_grouping_obj->getContainerType() != $container_type) {
310 continue;
311 }
312 // Check if container is current container
313 if ($tmp_grouping_obj->getContainerObjId() === $a_obj_id) {
314 $visible_groupings[] = $grouping_id;
315 continue;
316 }
317 // check if items are assigned
318 if (($items = $tmp_grouping_obj->getAssignedItems()) !== []) {
319 foreach ($items as $condition_data) {
320 if ($ilAccess->checkAccess('write', '', $condition_data['target_ref_id'])) {
321 $visible_groupings[] = $grouping_id;
322 break;
323 }
324 }
325 }
326 }
327 return $visible_groupings;
328 }
329
330 public function assign(int $a_crs_ref_id, int $a_course_id): void
331 {
332 // Add the parent course of grouping
333 $this->__addCondition($this->getContainerRefId(), $this->getContainerObjId());
334 $this->__addCondition($a_crs_ref_id, $a_course_id);
335 }
336
337 public function cloneGrouping(int $a_target_id, int $a_copy_id): void
338 {
339 $this->logger->debug('Start cloning membership limitations...');
340 $mappings = \ilCopyWizardOptions::_getInstance($a_copy_id)->getMappings();
341 $target_ref_id = 0;
342 $target_obj_id = 0;
343
344 if (array_key_exists($this->getContainerRefId(), $mappings) && $mappings[$this->getContainerRefId()]) {
345 $target_ref_id = $mappings[$this->getContainerRefId()];
346 $target_obj_id = \ilObject::_lookupObjId($target_ref_id);
347 $this->logger->dump($target_ref_id);
348 $this->logger->dump($target_obj_id);
349 }
350 if (!$target_ref_id || !$target_obj_id) {
351 $this->logger->debug('No target ref_id found.');
352 return;
353 }
354
355 $new_grouping = new \ilObjCourseGrouping();
356 $new_grouping->setTitle($this->getTitle());
357 $new_grouping->setDescription($this->getDescription());
358 $new_grouping->setContainerRefId($target_ref_id);
359 $new_grouping->setContainerObjId($target_obj_id);
360 $new_grouping->setContainerType(\ilObject::_lookupType($target_obj_id));
361 $new_grouping->setUniqueField($this->getUniqueField());
362 $new_grouping->create($target_ref_id, $target_obj_id);
363
364 $obj_instance = \ilObjectFactory::getInstanceByRefId($this->getContainerRefId(), false);
365 if (!$obj_instance instanceof \ilObject) {
366 $this->logger->info('Cannot create object instance for membership limitation');
367 return;
368 }
369 $limitation_items = self::_getGroupingItems($obj_instance);
370 $this->logger->dump($limitation_items);
371
372 foreach ($limitation_items as $item_ref_id) {
373 $target_item_ref_id = 0;
374 $target_item_obj_id = 0;
375 if (array_key_exists($item_ref_id, $mappings) && $mappings[$item_ref_id]) {
376 $target_item_ref_id = $mappings[$item_ref_id];
377 $target_item_obj_id = \ilObject::_lookupObjId($target_item_ref_id);
378 }
379 if (!$target_item_ref_id || !$target_item_obj_id) {
380 $this->logger->info('No mapping found for: ' . $item_ref_id);
381 continue;
382 }
383 $new_grouping->assign($target_item_ref_id, $target_item_obj_id);
384 }
385 }
386
387 public function __addCondition(int $a_target_ref_id, int $a_target_obj_id): void
388 {
389 $tmp_condh = new ilConditionHandler();
390 $tmp_condh->enableAutomaticValidation(false);
391
392 $tmp_condh->setTargetRefId($a_target_ref_id);
393 $tmp_condh->setTargetObjId($a_target_obj_id);
394 $tmp_condh->setTargetType(\ilObject::_lookupType($a_target_obj_id));
395 $tmp_condh->setTriggerRefId(0);
396 $tmp_condh->setTriggerObjId($this->getId());
397 $tmp_condh->setTriggerType('crsg');
398 $tmp_condh->setOperator('not_member');
399 $tmp_condh->setValue($this->getUniqueField());
400
401 if (!$tmp_condh->checkExists()) {
402 $tmp_condh->storeCondition();
403 }
404 }
405
406 public static function _deleteAll(int $a_course_id): void
407 {
408 global $DIC;
409
410 $ilDB = $DIC->database();
411
412 // DELETE CONDITIONS
413 foreach ($groupings = ilObjCourseGrouping::_getGroupings($a_course_id) as $grouping_id) {
414 $condh = new ilConditionHandler();
415 $condh->deleteByObjId($grouping_id);
416 }
417
418 $query = "DELETE FROM crs_groupings " .
419 "WHERE crs_id = " . $ilDB->quote($a_course_id, 'integer') . " ";
420 $res = $ilDB->manipulate($query);
421 }
422
427 public static function _getGroupings(int $a_course_id): array
428 {
429 global $DIC;
430
431 $ilDB = $DIC['ilDB'];
432
433 $query = "SELECT * FROM crs_groupings " .
434 "WHERE crs_id = " . $ilDB->quote($a_course_id, 'integer') . " ";
435
436 $res = $ilDB->query($query);
437 $groupings = [];
438 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
439 $groupings[] = (int) $row->crs_grp_id;
440 }
441 return $groupings;
442 }
443
444 public static function _checkCondition(int $trigger_obj_id, string $operator, $value, int $a_usr_id = 0): bool
445 {
446 // in the moment i alway return true, there are some problems with presenting the condition if it fails,
447 // only course register class check manually if this condition is fullfilled
448 return true;
449 }
450
454 public static function _getGroupingCourseIds(int $a_course_ref_id, int $a_course_id): array
455 {
456 global $DIC;
457
458 $tree = $DIC->repositoryTree();
459 // get all grouping ids the course is assigned to
460 $course_ids = [];
462 $a_course_ref_id,
463 $a_course_id,
464 'crs'
465 ) as $condition) {
466 if ($condition['trigger_type'] == 'crsg') {
468 'crsg',
469 $condition['trigger_obj_id']
470 ) as $target_condition) {
471 if ($tree->isDeleted($target_condition['target_ref_id'])) {
472 continue;
473 }
474 $course_ids[] = array('id' => $target_condition['target_obj_id'],
475 'unique' => $target_condition['value']
476 );
477 }
478 }
479 }
480 return $course_ids;
481 }
482
483 public static function getAssignedObjects(): array
484 {
486 }
487
488 public static function _checkGroupingDependencies(ilObject $container_obj, ?int $a_user_id = null): bool
489 {
490 global $DIC;
491
492 $ilUser = $DIC->user();
493 $lng = $DIC->language();
494 $tree = $DIC->repositoryTree();
495
496 $user_id = is_null($a_user_id) ? $ilUser->getId() : $a_user_id;
497 $trigger_ids = array();
499 $container_obj->getRefId(),
500 $container_obj->getId(),
501 $container_obj->getType()
502 ) as $condition) {
503 if ($condition['operator'] == 'not_member') {
504 $trigger_ids[] = $condition['trigger_obj_id'];
505 break;
506 }
507 }
508 if (count($trigger_ids) === 0) {
509 return true;
510 }
511 $matriculation_message = $assigned_message = '';
512 self::$assignedObjects = array();
513 foreach ($trigger_ids as $trigger_id) {
514 foreach (ilConditionHandler::_getPersistedConditionsOfTrigger('crsg', $trigger_id) as $condition) {
515 // Handle deleted items
516 if ($tree->isDeleted($condition['target_ref_id'])) {
517 continue;
518 }
519 if ($condition['operator'] == 'not_member') {
520 switch ($condition['value']) {
521 case 'matriculation':
523 if (!$matriculation_message) {
524 $matriculation_message = $lng->txt('crs_grp_matriculation_required');
525 }
526 }
527 }
528 if ($container_obj->getType() == 'crs') {
529 $members = ilCourseParticipants::_getInstanceByObjId($condition['target_obj_id']);
530 if ($members->isGroupingMember($user_id, $condition['value'])) {
531 if (!$assigned_message) {
532 self::$assignedObjects[] = $condition['target_obj_id'];
533 $assigned_message = $lng->txt('crs_grp_already_assigned');
534 }
535 }
536 } elseif ($container_obj->getType() == 'grp') {
537 $members = ilGroupParticipants::_getInstanceByObjId($condition['target_obj_id']);
538 if ($members->isGroupingMember($user_id, $condition['value'])) {
539 if (!$assigned_message) {
540 self::$assignedObjects[] = $condition['target_obj_id'];
541 $assigned_message = $lng->txt('grp_grp_already_assigned');
542 }
543 }
544 } elseif (ilObjGroup::_isMember($user_id, $condition['target_ref_id'], $condition['value'])) {
545 if (!$assigned_message) {
546 self::$assignedObjects[] = $condition['target_obj_id'];
547 $assigned_message = $lng->txt('crs_grp_already_assigned');
548 }
549 }
550 }
551 }
552 }
553 if ($matriculation_message) {
554 $container_obj->appendMessage($matriculation_message);
555 return false;
556 } elseif ($assigned_message) {
557 $container_obj->appendMessage($assigned_message);
558 return false;
559 }
560 return true;
561 }
562
566 public static function _getGroupingItems(ilObject $container_obj): array
567 {
568 global $DIC;
569
570 $tree = $DIC->repositoryTree();
571 $ilObjDataCache = $DIC['ilObjDataCache'];
572 $ilAccess = $DIC->access();
573 $tree = $DIC->repositoryTree();
574
575 $trigger_ids = array();
577 $container_obj->getRefId(),
578 $container_obj->getId(),
579 $container_obj->getType()
580 ) as $condition) {
581 if ($condition['operator'] == 'not_member') {
582 $trigger_ids[] = $condition['trigger_obj_id'];
583 }
584 }
585 if ($trigger_ids === []) {
586 return [];
587 }
588 $hash_table = array();
589 $items = [];
590 foreach ($trigger_ids as $trigger_id) {
591 foreach (ilConditionHandler::_getPersistedConditionsOfTrigger('crsg', $trigger_id) as $condition) {
592 // Continue if trigger is deleted
593 if ($tree->isDeleted($condition['target_ref_id'])) {
594 continue;
595 }
596
597 if ($condition['operator'] == 'not_member') {
598 if (!($hash_table[$condition['target_ref_id']] ?? false)) {
599 $items[] = $condition['target_ref_id'];
600 }
601 $hash_table[$condition['target_ref_id']] = true;
602 }
603 }
604 }
605 return $items;
606 }
607} // END class.ilObjCourseGrouping
INTERNAL CLASS: Please do not use in consumer code.
static _getPersistedConditionsOfTarget(int $a_target_ref_id, int $a_target_obj_id, string $a_target_type="")
get all persisted conditions of target object
static _getPersistedConditionsOfTrigger(string $a_trigger_obj_type, int $a_trigger_id)
Get all persisted conditions of trigger object Note: This only gets persisted conditions NOT (dynamic...
static _getInstance(int $a_copy_id)
static _getInstanceByObjId(int $a_obj_id)
static _getInstanceByObjId(int $a_obj_id)
Get singleton instance.
Component logger with individual log levels by component id.
Class ilObj<module_name>
create(int $a_course_ref_id, int $a_course_id)
static _getGroupingCourseIds(int $a_course_ref_id, int $a_course_id)
Get all ids of courses that are grouped with another course.
assign(int $a_crs_ref_id, int $a_course_id)
static _getVisibleGroupings(int $a_obj_id)
Returns a list of all groupings for which the current user hast write permission on all assigned obje...
cloneGrouping(int $a_target_id, int $a_copy_id)
static _getGroupingItems(ilObject $container_obj)
Get courses/groups that are assigned to the same membership limitation.
static _deleteAll(int $a_course_id)
static _getGroupings(int $a_course_id)
static _checkCondition(int $trigger_obj_id, string $operator, $value, int $a_usr_id=0)
ilObjectDataCache $objectDataCache
static _checkGroupingDependencies(ilObject $container_obj, ?int $a_user_id=null)
__addCondition(int $a_target_ref_id, int $a_target_obj_id)
_isMember(int $a_user_id, int $a_ref_id, string $a_field='')
User class.
static lookupMatriculation(int $a_usr_id)
class ilObjectDataCache
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
Class ilObject Basic functions for all objects.
static _lookupType(int $id, bool $reference=false)
static _lookupObjId(int $ref_id)
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
isDeleted(int $a_node_id)
This is a wrapper for isSaved() with a more useful name.
Interface ilAccessHandler This interface combines all available interfaces which can be called via gl...
Interface ilDBInterface.
$res
Definition: ltiservices.php:69
global $lng
Definition: privfeed.php:31
global $DIC
Definition: shib_login.php:26