ILIAS  release_8 Revision v8.25-1-g13de6a5eca6
class.ilLPCollectionOfRepositoryObjects.php
Go to the documentation of this file.
1<?php
2
3declare(strict_types=0);
4
5/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
6
13{
14 protected static array $possible_items = array();
15
16 protected ilTree $tree;
18
19 public function __construct(int $a_obj_id, int $a_mode)
20 {
21 global $DIC;
22
23 $this->tree = $DIC->repositoryTree();
24 $this->objDefinition = $DIC['objDefinition'];
25
26 parent::__construct($a_obj_id, $a_mode);
27 }
28
29 public function getPossibleItems(
30 int $a_ref_id,
31 bool $a_full_data = false
32 ): array {
33 global $DIC;
34
35 $cache_idx = $a_ref_id . "__" . $a_full_data;
36 if (!isset(self::$possible_items[$cache_idx])) {
37 $all_possible = array();
38
39 if (!$this->tree->isDeleted($a_ref_id)) {
40 if (!$a_full_data) {
41 $data = $this->tree->getRbacSubtreeInfo($a_ref_id);
42 } else {
43 $node = $this->tree->getNodeData($a_ref_id);
44 $data = $this->tree->getSubTree($node);
45 }
46 foreach ($data as $node) {
47 if (!$a_full_data) {
48 $item_ref_id = (int) $node['child'];
49 } else {
50 $item_ref_id = (int) $node['ref_id'];
51 }
52
53 // avoid recursion
54 if ($item_ref_id == $a_ref_id || !$this->validateEntry(
55 $item_ref_id
56 )) {
57 continue;
58 }
59
60 switch ($node['type']) {
61 case 'sess':
62 case 'exc':
63 case 'fold':
64 case 'grp':
65 case 'sahs':
66 case 'lm':
67 case 'tst':
68 case 'file':
69 case 'mcst':
70 case 'htlm':
71 case 'svy':
72 case "prg":
73 case 'iass':
74 case 'copa':
75 case 'frm':
76 case 'cmix':
77 case 'lti':
78 case 'lso':
79 case 'crsr':
80 if (!$a_full_data) {
81 $all_possible[] = $item_ref_id;
82 } else {
83 $all_possible[$item_ref_id] = array(
84 'ref_id' => (int) $item_ref_id,
85 'obj_id' => (int) $node['obj_id'],
86 'title' => (string) $node['title'],
87 'description' => (string) $node['description'],
88 'type' => (string) $node['type']
89 );
90 }
91 break;
92
93 // repository plugin object?
94 case $this->objDefinition->isPluginTypeName(
95 $node['type']
96 ):
97 $only_active = false;
98 if (!$this->isAssignedEntry($item_ref_id)) {
99 $only_active = true;
100 }
102 $node['type'],
103 $only_active
104 )) {
105 if (!$a_full_data) {
106 $all_possible[] = $item_ref_id;
107 } else {
108 $all_possible[$item_ref_id] = array(
109 'ref_id' => (int) $item_ref_id,
110 'obj_id' => (int) $node['obj_id'],
111 'title' => (string) $node['title'],
112 'description' => (string) $node['description'],
113 'type' => (string) $node['type']
114 );
115 }
116 }
117 break;
118 }
119 }
120 }
121
122 self::$possible_items[$cache_idx] = $all_possible;
123 }
124
125 return self::$possible_items[$cache_idx];
126 }
127
128 protected function validateEntry(int $a_item_id): bool
129 {
130 $a_item_type = ilObject::_lookupType($a_item_id, true);
131 // this is hardcoded so we do not need to call all ObjectLP types
132 if ($a_item_type == 'tst') {
133 // Check anonymized
134 $item_obj_id = ilObject::_lookupObjId($a_item_id);
135 $olp = ilObjectLP::getInstance($item_obj_id);
136 if ($olp->isAnonymized()) {
137 return false;
138 }
139 }
140 return true;
141 }
142
143 public function cloneCollection(int $a_target_id, int $a_copy_id): void
144 {
145 parent::cloneCollection($a_target_id, $a_copy_id);
146
147 $cwo = ilCopyWizardOptions::_getInstance($a_copy_id);
148 $mappings = $cwo->getMappings();
149
150 $target_obj_id = ilObject::_lookupObjId($a_target_id);
151 $target_collection = new static($target_obj_id, $this->mode);
152
153 // clone (active) groupings
154 foreach ($this->getGroupedItemsForLPStatus(
155 ) as $grouping_id => $group) {
156 $target_item_ids = array();
157 foreach ($group["items"] as $item) {
158 if (!isset($mappings[$item]) or !$mappings[$item]) {
159 continue;
160 }
161
162 $target_item_ids[] = $mappings[$item];
163 }
164
165 // grouping - if not only single item left after copy?
166 if ($grouping_id && sizeof($target_item_ids) > 1) {
167 // should not be larger than group
168 $num_obligatory = min(
169 sizeof($target_item_ids),
170 $group["num_obligatory"]
171 );
172
173 $target_collection->createNewGrouping(
174 $target_item_ids,
175 $num_obligatory
176 );
177 } else {
178 // #15487 - single items
179 foreach ($target_item_ids as $item_id) {
180 $this->addEntry($item_id);
181 }
182 }
183 }
184 }
185
186 protected function read(int $a_obj_id): void
187 {
188 $items = array();
189
190 $ref_ids = ilObject::_getAllReferences($a_obj_id);
191 $ref_id = end($ref_ids);
192 $possible = $this->getPossibleItems($ref_id);
193
194 $res = $this->db->query(
195 "SELECT utc.item_id, obd.type" .
196 " FROM ut_lp_collections utc" .
197 " JOIN object_reference obr ON item_id = ref_id" .
198 " JOIN object_data obd ON obr.obj_id = obd.obj_id" .
199 " WHERE utc.obj_id = " . $this->db->quote($a_obj_id, "integer") .
200 " AND active = " . $this->db->quote(1, "integer") .
201 " ORDER BY title"
202 );
203 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
204 if (in_array($row->item_id, $possible) &&
205 $this->validateEntry((int) $row->item_id)) {
206 $items[] = $row->item_id;
207 } else {
208 $this->deleteEntry((int) $row->item_id);
209 }
210 }
211
212 $this->items = $items;
213 }
214
215 protected function addEntry(int $a_item_id): bool
216 {
217 // only active entries are assigned!
218 if (!$this->isAssignedEntry($a_item_id)) {
219 // #13278 - because of grouping inactive items may exist
220 $this->deleteEntry($a_item_id);
221
222 $query = "INSERT INTO ut_lp_collections" .
223 " (obj_id, lpmode, item_id, grouping_id, num_obligatory, active)" .
224 " VALUES (" . $this->db->quote($this->obj_id, "integer") .
225 ", " . $this->db->quote($this->mode, "integer") .
226 ", " . $this->db->quote($a_item_id, "integer") .
227 ", " . $this->db->quote(0, "integer") .
228 ", " . $this->db->quote(0, "integer") .
229 ", " . $this->db->quote(1, "integer") .
230 ")";
231 $this->db->manipulate($query);
232 $this->items[] = $a_item_id;
233 }
234 return true;
235 }
236
237 protected function deleteEntry(int $a_item_id): bool
238 {
239 $query = "DELETE FROM ut_lp_collections " .
240 " WHERE obj_id = " . $this->db->quote($this->obj_id, "integer") .
241 " AND item_id = " . $this->db->quote($a_item_id, "integer") .
242 " AND grouping_id = " . $this->db->quote(0, "integer");
243 $this->db->manipulate($query);
244 return true;
245 }
246
247 public static function hasGroupedItems(int $a_obj_id): bool
248 {
249 global $DIC;
250
251 $ilDB = $DIC['ilDB'];
252 $query = "SELECT item_id FROM ut_lp_collections" .
253 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer") .
254 " AND grouping_id > " . $ilDB->quote(0, "integer");
255 $res = $ilDB->query($query);
256 return $res->numRows() ? true : false;
257 }
258
259 protected function getGroupingIds(array $a_item_ids): array
260 {
261 global $DIC;
262
263 $ilDB = $DIC['ilDB'];
264
265 $grouping_ids = array();
266
267 $query = "SELECT grouping_id FROM ut_lp_collections" .
268 " WHERE obj_id = " . $this->db->quote($this->obj_id, "integer") .
269 " AND " . $this->db->in("item_id", $a_item_ids, false, "integer") .
270 " AND grouping_id > " . $this->db->quote(0, "integer");
271 $res = $this->db->query($query);
272 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
273 $grouping_ids[] = $row->grouping_id;
274 }
275
276 return $grouping_ids;
277 }
278
279 public function deactivateEntries(array $a_item_ids): void
280 {
281 parent::deactivateEntries($a_item_ids);
282
283 $grouping_ids = $this->getGroupingIds($a_item_ids);
284 if ($grouping_ids) {
285 $query = "UPDATE ut_lp_collections" .
286 " SET active = " . $this->db->quote(0, "integer") .
287 " WHERE " . $this->db->in(
288 "grouping_id",
289 $grouping_ids,
290 false,
291 "integer"
292 ) .
293 " AND obj_id = " . $this->db->quote($this->obj_id, "integer");
294 $this->db->manipulate($query);
295 }
296 }
297
298 public function activateEntries(array $a_item_ids): void
299 {
300 parent::activateEntries($a_item_ids);
301
302 $grouping_ids = $this->getGroupingIds($a_item_ids);
303 if ($grouping_ids) {
304 $query = "UPDATE ut_lp_collections" .
305 " SET active = " . $this->db->quote(1, "integer") .
306 " WHERE " . $this->db->in(
307 "grouping_id",
308 $grouping_ids,
309 false,
310 "integer"
311 ) .
312 " AND obj_id = " . $this->db->quote($this->obj_id, "integer");
313 $this->db->manipulate($query);
314 }
315 }
316
317 public function createNewGrouping(
318 array $a_item_ids,
319 int $a_num_obligatory = 1
320 ): void {
321 $this->activateEntries($a_item_ids);
322
323 $all_item_ids = array();
324 $grouping_ids = $this->getGroupingIds($a_item_ids);
325 $query = "SELECT item_id FROM ut_lp_collections" .
326 " WHERE obj_id = " . $this->db->quote($this->obj_id, "integer") .
327 " AND " . $this->db->in(
328 "grouping_id",
329 $grouping_ids,
330 false,
331 "integer"
332 );
333 $res = $this->db->query($query);
334 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
335 $all_item_ids[] = $row->item_id;
336 }
337
338 $all_item_ids = array_unique(array_merge($all_item_ids, $a_item_ids));
339
340 $this->releaseGrouping($a_item_ids);
341
342 // Create new grouping
343 $query = "SELECT MAX(grouping_id) grp FROM ut_lp_collections" .
344 " WHERE obj_id = " . $this->db->quote($this->obj_id, "integer") .
345 " GROUP BY obj_id";
346 $res = $this->db->query($query);
347 $row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT);
348 $grp_id = $row->grp;
349 ++$grp_id;
350
351 $query = "UPDATE ut_lp_collections SET" .
352 " grouping_id = " . $this->db->quote($grp_id, "integer") .
353 ", num_obligatory = " . $this->db->quote(
354 $a_num_obligatory,
355 "integer"
356 ) .
357 ", active = " . $this->db->quote(1, "integer") .
358 " WHERE obj_id = " . $this->db->quote($this->obj_id, "integer") .
359 " AND " . $this->db->in("item_id", $all_item_ids, false, "integer");
360 $this->db->manipulate($query);
361 }
362
363 public function releaseGrouping(array $a_item_ids): void
364 {
365 $grouping_ids = $this->getGroupingIds($a_item_ids);
366
367 $query = "UPDATE ut_lp_collections" .
368 " SET grouping_id = " . $this->db->quote(0, "integer") .
369 ", num_obligatory = " . $this->db->quote(0, "integer") .
370 " WHERE obj_id = " . $this->db->quote($this->obj_id, "integer") .
371 " AND " . $this->db->in(
372 "grouping_id",
373 $grouping_ids,
374 false,
375 "integer"
376 );
377 $this->db->manipulate($query);
378 }
379
380 public function saveObligatoryMaterials(array $a_obl): void
381 {
382 foreach ($a_obl as $grouping_id => $num) {
383 $query = "SELECT count(obj_id) num FROM ut_lp_collections" .
384 " WHERE obj_id = " . $this->db->quote(
385 $this->obj_id,
386 "integer"
387 ) .
388 " AND grouping_id = " . $this->db->quote(
389 $grouping_id,
390 'integer'
391 ) .
392 " GROUP BY obj_id";
393 $res = $this->db->query($query);
394 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
395 if ($num <= 0 || $num >= $row->num) {
396 throw new UnexpectedValueException();
397 }
398 }
399 }
400 foreach ($a_obl as $grouping_id => $num) {
401 $query = "UPDATE ut_lp_collections" .
402 " SET num_obligatory = " . $this->db->quote($num, "integer") .
403 " WHERE obj_id = " . $this->db->quote(
404 $this->obj_id,
405 "integer"
406 ) .
407 " AND grouping_id = " . $this->db->quote(
408 $grouping_id,
409 "integer"
410 );
411 $this->db->manipulate($query);
412 }
413 }
414
415 public function getTableGUIData(int $a_parent_ref_id): array
416 {
417 $items = $this->getPossibleItems($a_parent_ref_id, true);
418
419 $data = array();
420 $done = array();
421 foreach ($items as $item_id => $item) {
422 if (in_array($item_id, $done)) {
423 continue;
424 }
425
426 $table_item = $this->parseTableGUIItem($item_id, $item);
427
428 // grouping
429 $table_item['grouped'] = array();
430 $grouped_items = $this->getTableGUItemGroup($item_id);
431 if (count((array) ($grouped_items['items'] ?? [])) > 1) {
432 foreach ($grouped_items['items'] as $grouped_item_id) {
433 if ($grouped_item_id == $item_id ||
434 !is_array($items[$grouped_item_id] ?? false)) { // #15498
435 continue;
436 }
437
438 $table_item['grouped'][] = $this->parseTableGUIItem(
439 $grouped_item_id,
440 $items[$grouped_item_id]
441 );
442 $table_item['num_obligatory'] = $grouped_items['num_obligatory'];
443 $table_item['grouping_id'] = $grouped_items['grouping_id'];
444
445 $done[] = $grouped_item_id;
446 }
447 }
448 $data[] = $table_item;
449 }
450 return $data;
451 }
452
453 protected function parseTableGUIItem(int $a_id, array $a_item): array
454 {
455 $table_item = $a_item;
456 $table_item['id'] = $a_id;
457 $table_item['status'] = $this->isAssignedEntry($a_id);
458
459 $olp = ilObjectLP::getInstance($a_item['obj_id']);
460 $table_item['mode_id'] = $olp->getCurrentMode();
461 $table_item['mode'] = $olp->getModeText($table_item['mode_id']);
462 $table_item['anonymized'] = $olp->isAnonymized();
463
464 return $table_item;
465 }
466
467 protected function getTableGUItemGroup(int $item_id): array
468 {
469 $items = array();
470 $query = "SELECT grouping_id FROM ut_lp_collections" .
471 " WHERE obj_id = " . $this->db->quote($this->obj_id, "integer") .
472 " AND item_id = " . $this->db->quote($item_id, "integer");
473 $res = $this->db->query($query);
474 $grouping_id = 0;
475 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
476 $grouping_id = (int) $row->grouping_id;
477 }
478 if ($grouping_id > 0) {
479 $query = "SELECT item_id, num_obligatory FROM ut_lp_collections" .
480 " WHERE obj_id = " . $this->db->quote(
481 $this->obj_id,
482 "integer"
483 ) .
484 " AND grouping_id = " . $this->db->quote(
485 $grouping_id,
486 "integer"
487 );
488 $res = $this->db->query($query);
489 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
490 $items['items'][] = (int) $row->item_id;
491 $items['num_obligatory'] = (int) $row->num_obligatory;
492 $items['grouping_id'] = (int) $grouping_id;
493 }
494 }
495 return $items;
496 }
497
498 public function getGroupedItemsForLPStatus(): array
499 {
500 $items = $this->getItems();
501 $query = " SELECT * FROM ut_lp_collections" .
502 " WHERE obj_id = " . $this->db->quote($this->obj_id, "integer") .
503 " AND active = " . $this->db->quote(1, "integer");
504 $res = $this->db->query($query);
505
506 $grouped = array();
507 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
508 if (in_array($row->item_id, $items)) {
509 $grouped[$row->grouping_id]['items'][] = (int) $row->item_id;
510 $grouped[$row->grouping_id]['num_obligatory'] = (int) $row->num_obligatory;
511 }
512 }
513 return $grouped;
514 }
515}
return true
static _getInstance(int $a_copy_id)
getPossibleItems(int $a_ref_id, bool $a_full_data=false)
createNewGrouping(array $a_item_ids, int $a_num_obligatory=1)
LP collection base class.
isAssignedEntry(int $a_item_id)
parses the objects.xml it handles the xml-description of all ilias objects
static getInstance(int $obj_id)
static _lookupType(int $id, bool $reference=false)
static _getAllReferences(int $id)
get all reference ids for object ID
static _lookupObjId(int $ref_id)
static isTypePluginWithLP(string $a_type, bool $a_active_status=true)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
global $DIC
Definition: feed.php:28
$ref_id
Definition: ltiauth.php:67
$res
Definition: ltiservices.php:69
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$query