ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilLPStatusCollection.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
26{
27 private ilTree $tree;
28
29 public function __construct(int $a_obj_id)
30 {
31 global $DIC;
32
33 parent::__construct($a_obj_id);
34 $this->tree = $DIC->repositoryTree();
35 }
36
37 public static function _getNotAttempted(int $a_obj_id): array
38 {
39 $users = array();
40
41 $members = self::getMembers($a_obj_id);
42 if ($members) {
43 // diff in progress and completed (use stored result in LPStatusWrapper)
44 $users = array_diff(
45 (array) $members,
47 );
48 $users = array_diff(
49 $users,
51 );
52 $users = array_diff(
53 $users,
55 );
56 }
57
58 return $users;
59 }
60
61 public static function _getInProgress(int $a_obj_id): array
62 {
63 $users = ilChangeEvent::lookupUsersInProgress($a_obj_id);
64
65 $olp = ilObjectLP::getInstance($a_obj_id);
66 $collection = $olp->getCollectionInstance();
67 if ($collection) {
68 foreach ($collection->getItems() as $item_id) {
69 $item_id = ilObject::_lookupObjId($item_id);
70
71 // merge arrays of users with status 'in progress'
72 $users = array_unique(
73 array_merge(
74 $users,
76 )
77 );
78 $users = array_unique(
79 array_merge(
80 $users,
82 )
83 );
84 }
85 }
86
87 // Exclude all users with status completed.
88 $users = array_diff(
89 $users,
91 );
92 // Exclude all users with status failed.
93 $users = array_diff($users, ilLPStatusWrapper::_getFailed($a_obj_id));
94
95 if ($users) {
96 // Exclude all non members
97 $users = array_intersect(self::getMembers($a_obj_id), $users);
98 }
99
100 return $users;
101 }
102
107 public static function _getCompleted(int $a_obj_id): array
108 {
109 global $DIC;
110
111 $ilObjDataCache = $DIC['ilObjDataCache'];
112
113 $olp = ilObjectLP::getInstance($a_obj_id);
114 $collection = $olp->getCollectionInstance();
115 $grouped_items = [];
116 if ($collection) {
117 $grouped_items = $collection->getGroupedItemsForLPStatus();
118 }
119 if (!count($grouped_items)) {
120 // #11513 - empty collections cannot be completed
121 return array();
122 } else {
123 // New handling for optional assignments
124 $counter = 0;
125 $users = array();
126 foreach ($grouped_items as $grouping_id => $grouping) {
127 $isGrouping = $grouping_id ? true : false;
128 $grouping_completed = array();
129 $grouping_completed_users_num = array();
130 foreach ((array) $grouping['items'] as $item) {
131 $item_id = $ilObjDataCache->lookupObjId((int) $item);
132 $tmp_users = ilLPStatusWrapper::_getCompleted($item_id);
133 if ($isGrouping) {
134 // Iterated through all grouped items and count the number of fullfiled items
135 foreach ($tmp_users as $tmp_user_id) {
136 $grouping_completed_users_num[$tmp_user_id] =
137 ($grouping_completed_users_num[$tmp_user_id] ?? 0) + 1;
138 }
139 } elseif (!$counter++) {
140 $users = $tmp_users;
141 } else {
142 $users = array_intersect($users, $tmp_users);
143 }
144 }
145 if ($isGrouping) {
146 // Iterate through all "grouping_completed_users_num"
147 // All users with completed items greater equal than "num_obligatory" are completed
148 foreach ($grouping_completed_users_num as $tmp_user_id => $grouping_num_completed) {
149 if ($grouping_num_completed >= $grouping['num_obligatory']) {
150 $grouping_completed[] = $tmp_user_id;
151 }
152 }
153
154 // build intersection of users
155 if (!$counter++) {
156 $users = $grouping_completed;
157 } else {
158 $users = array_intersect($users, $grouping_completed);
159 }
160 }
161 }
162 }
163
164 $users = array_diff($users, ilLPStatusWrapper::_getFailed($a_obj_id));
165
166 if ($users) {
167 // Exclude all non members
168 $users = array_intersect(self::getMembers($a_obj_id), $users);
169 }
170
171 return (array) $users;
172 }
173
174 public static function _getFailed(int $a_obj_id): array
175 {
176 global $DIC;
177
178 $ilObjDataCache = $DIC['ilObjDataCache'];
179
180 $users = array();
181
182 $olp = ilObjectLP::getInstance($a_obj_id);
183 $collection = $olp->getCollectionInstance();
184 if ($collection) {
185 foreach ($collection->getGroupedItemsForLPStatus(
186 ) as $grouping_id => $grouping) {
187 $isGrouping = $grouping_id ? true : false;
188
189 $gr_failed = array();
190 $gr_failed_users_num = array();
191 $counter = 0;
192 foreach ((array) $grouping['items'] as $item) {
193 $item_id = $ilObjDataCache->lookupObjId((int) $item);
194 $tmp_users = ilLPStatusWrapper::_getFailed($item_id);
195
196 if ($isGrouping) {
197 foreach ($tmp_users as $tmp_user_id) {
198 $gr_failed_users_num[$tmp_user_id] =
199 ($gr_failed_users_num[$tmp_user_id] ?? 0) + 1;
200 }
201 } else {
202 // One item failed is sufficient for status failed.
203 $gr_failed = array_merge($gr_failed, $tmp_users);
204 }
205 $counter++;
206 }
207 if ($isGrouping) {
208 $allowed_failed = count(
209 $grouping['items']
210 ) - $grouping['num_obligatory'];
211 // Itereate over all failed users and check whether the allowd_failed value exceeded
212 foreach ($gr_failed_users_num as $tmp_user_id => $num_failed) {
213 if ($num_failed > $allowed_failed) {
214 $gr_failed[] = $tmp_user_id;
215 }
216 }
217 }
218 $users = array_unique(array_merge($users, $gr_failed));
219 }
220 }
221
222 if ($users) {
223 // Exclude all non members
224 $users = array_intersect(self::getMembers($a_obj_id), $users);
225 }
226
227 return array_unique($users);
228 }
229
230 public static function _getStatusInfo(int $a_obj_id): array
231 {
232 $status_info = array();
233
234 $olp = ilObjectLP::getInstance($a_obj_id);
235 $collection = $olp->getCollectionInstance();
236 if ($collection) {
237 $status_info['collections'] = $collection->getItems();
238 $status_info['num_collections'] = count(
239 $status_info['collections']
240 );
241 }
242
243 return $status_info;
244 }
245
246 public static function _getTypicalLearningTime(string $type, int $obj_id, int $sub_id = 0): int
247 {
248 global $DIC;
249
250 $ilObjDataCache = $DIC['ilObjDataCache'];
251
252 if ($type == 'sahs') {
253 return parent::_getTypicalLearningTime($type, $obj_id);
254 }
255
256 $tlt = 0;
258 foreach ($status_info['collections'] as $item) {
259 $obj_id = $ilObjDataCache->lookupObjId((int) $item);
262 $type,
263 $obj_id
264 );
265 }
266 return $tlt;
267 }
268
269 public function determineStatus(
270 int $a_obj_id,
271 int $a_usr_id,
272 ?object $a_obj = null
273 ): int {
274 global $DIC;
275
276 $ilObjDataCache = $DIC['ilObjDataCache'];
277
278 $status['completed'] = true;
279 $status['failed'] = false;
280 $status['in_progress'] = false;
281
282 switch ($this->ilObjDataCache->lookupType($a_obj_id)) {
283 case "crs":
284 case "fold":
285 case "grp":
286 case "lso":
287 if (ilChangeEvent::hasAccessed($a_obj_id, $a_usr_id)) {
288 $status['in_progress'] = true;
289 }
290
291 $olp = ilObjectLP::getInstance($a_obj_id);
292 $collection = $olp->getCollectionInstance();
293 $grouped_items = [];
294 if ($collection) {
295 $grouped_items = $collection->getGroupedItemsForLPStatus();
296 }
297 if (!count($grouped_items)) {
298 // #11513 - empty collections cannot be completed
299 $status['completed'] = false;
300 } else {
301 foreach ($grouped_items as $grouping_id => $grouping) {
302 $isGrouping = $grouping_id ? true : false;
304 $status,
305 $grouping,
306 $a_usr_id,
307 $isGrouping
308 );
309 }
310 }
311
312 if ($status['completed']) {
313 if (!$this->isMember((int) $a_obj_id, (int) $a_usr_id)) {
315 }
316
318 }
319
320 if ($status['failed']) {
322 }
323
324 if ($status['in_progress']) {
326 }
327 break;
328 }
330 }
331
335 public static function determineGroupingStatus(
336 array $status,
337 array $gr_info,
338 int $user_id,
339 bool $is_grouping
340 ): array {
341 global $DIC;
342
343 $ilObjDataCache = $DIC['ilObjDataCache'];
344
345 $items = $gr_info['items'];
346 if ($is_grouping) {
347 $max_allowed_failed = count($items) - $gr_info['num_obligatory'];
348 $required_completed = $gr_info['num_obligatory'];
349 } else {
350 $max_allowed_failed = 0;
351 $required_completed = count($items);
352 }
353
354 // Required for grouping with a number of obligatory items
355 $num_failed = 0;
356 $num_completed = 0;
357
358 foreach ($items as $item_id) {
359 $item_id = $ilObjDataCache->lookupObjId((int) $item_id);
361 $item_id,
363 );
364
365 if ($gr_status == self::LP_STATUS_FAILED_NUM) {
366 if (++$num_failed > $max_allowed_failed) {
367 $status['failed'] = true;
368 $status['completed'] = false;
369 return $status;
370 }
371 }
372 if ($gr_status == self::LP_STATUS_COMPLETED_NUM) {
373 if (++$num_completed >= $required_completed) {
374 return $status;
375 }
376 }
377 }
378 // Not completed since returned above
379 $status['completed'] = false;
380 return $status;
381 }
382
388 protected function isMember(int $objId, int $usrId): bool
389 {
390 switch ($this->ilObjDataCache->lookupType($objId)) {
391 case 'crs':
392 $participants = ilCourseParticipant::_getInstanceByObjId($objId, $usrId);
393 return $participants->isMember();
394
395 case 'grp':
397 return $participants->isMember($usrId);
398
399 case 'fold':
400 $folderRefIds = ilObject::_getAllReferences($objId);
401 $folderRefId = current($folderRefIds);
402 if ($crsRefId = $this->tree->checkForParentType($folderRefId, 'crs')) {
403 $participants = ilCourseParticipant::_getInstanceByObjId(ilObject::_lookupObjId($crsRefId), $usrId);
404 return $participants->isMember();
405 }
406
407 if ($grpRefId = $this->tree->checkForParentType($folderRefId, 'grp')) {
409 return $participants->isMember($usrId);
410 }
411 break;
412
413 case 'lso':
415 return $participants->isMember($usrId);
416 }
417
418 return true;
419 }
420
426 protected static function getMembers(int $a_obj_id): array
427 {
428 global $DIC;
429
430 $ilObjDataCache = $DIC['ilObjDataCache'];
431 $tree = $DIC['tree'];
432
433 switch ($ilObjDataCache->lookupType($a_obj_id)) {
434 case 'crs':
436 $a_obj_id
437 );
438 return $member_obj->getMembers();
439
440 case 'grp':
442 $a_obj_id
443 );
444 return $member_obj->getMembers();
445
446 case 'fold':
447 $folder_ref_ids = ilObject::_getAllReferences($a_obj_id);
448 $folder_ref_id = current($folder_ref_ids);
449 if ($crs_id = $tree->checkForParentType(
450 $folder_ref_id,
451 'crs'
452 )) {
455 );
456 return $member_obj->getMembers();
457 }
458 if ($grp_id = $tree->checkForParentType(
459 $folder_ref_id,
460 'grp'
461 )) {
464 );
465 return $member_obj->getMembers();
466 }
467 break;
468
469 case 'lso':
471 $a_obj_id
472 );
473 return $member_obj->getMembers();
474 break;
475 }
476
477 return array();
478 }
479
483 public static function _lookupCompletedForObject(
484 int $a_obj_id,
485 ?array $a_user_ids = null
486 ): array {
487 if (!$a_user_ids) {
488 $a_user_ids = self::getMembers($a_obj_id);
489 if (!$a_user_ids) {
490 return array();
491 }
492 }
493 return self::_lookupStatusForObject(
494 $a_obj_id,
495 self::LP_STATUS_COMPLETED_NUM,
496 $a_user_ids
497 );
498 }
499
503 public static function _lookupFailedForObject(
504 int $a_obj_id,
505 ?array $a_user_ids = null
506 ): array {
507 if (!$a_user_ids) {
508 $a_user_ids = self::getMembers($a_obj_id);
509 if (!$a_user_ids) {
510 return array();
511 }
512 }
513 return self::_lookupStatusForObject(
514 $a_obj_id,
515 self::LP_STATUS_FAILED_NUM,
516 $a_user_ids
517 );
518 }
519
523 public static function _lookupInProgressForObject(
524 int $a_obj_id,
525 ?array $a_user_ids = null
526 ): array {
527 if (!$a_user_ids) {
528 $a_user_ids = self::getMembers($a_obj_id);
529 if (!$a_user_ids) {
530 return array();
531 }
532 }
533 return self::_lookupStatusForObject(
534 $a_obj_id,
535 self::LP_STATUS_IN_PROGRESS_NUM,
536 $a_user_ids
537 );
538 }
539
540 public function determinePercentage(int $a_obj_id, int $a_usr_id, ?object $a_obj = null): int
541 {
542 $status_info = self::_getStatusInfo($a_obj_id);
543 if (empty($status_info)) {
544 return 0;
545 }
546 $passed = 0;
547 foreach ($status_info['collections'] as $item_ref_id) {
548 $obj_id = ilObject::_lookupObjId($item_ref_id);
549 if (ilLPStatusWrapper::_determineStatus($obj_id, $a_usr_id) === self::LP_STATUS_COMPLETED_NUM) {
550 $passed++;
551 }
552 }
553 $percentage = 0;
554 if ($status_info["num_collections"] > 0) {
555 $percentage = (int) ((100.0 / $status_info["num_collections"]) * $passed);
556 }
557 return $percentage;
558 }
559}
return true
static hasAccessed(int $a_obj_id, int $a_usr_id)
Has accessed.
static lookupUsersInProgress(int $a_obj_id)
static _getInstanceByObjId(int $a_obj_id, int $a_usr_id)
static _getInstanceByObjId(int $a_obj_id)
static _getInstanceByObjId(int $a_obj_id)
Get singleton instance.
determinePercentage(int $a_obj_id, int $a_usr_id, ?object $a_obj=null)
isMember(int $objId, int $usrId)
static _getTypicalLearningTime(string $type, int $obj_id, int $sub_id=0)
static _getStatusInfo(int $a_obj_id)
static _getCompleted(int $a_obj_id)
Get completed users New handling for optional grouped assignments.
static _lookupInProgressForObject(int $a_obj_id, ?array $a_user_ids=null)
Get in progress users for object.
static determineGroupingStatus(array $status, array $gr_info, int $user_id, bool $is_grouping)
Determine grouping status.
static _lookupFailedForObject(int $a_obj_id, ?array $a_user_ids=null)
Get failed users for object.
static _getInProgress(int $a_obj_id)
determineStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null)
static _getNotAttempted(int $a_obj_id)
static getMembers(int $a_obj_id)
Get members for object.
static _getFailed(int $a_obj_id)
static _lookupCompletedForObject(int $a_obj_id, ?array $a_user_ids=null)
Get completed users for object.
static _getInProgress(int $a_obj_id)
Static function to read users who have the status 'in_progress'.
static _getFailed(int $a_obj_id)
Static function to read the users who have the status 'completed'.
static _determineStatus(int $a_obj_id, int $a_usr_id)
static _getTypicalLearningTime(string $type, int $a_obj_id)
Reads Typical learning time.
static _getCompleted(int $a_obj_id)
Static function to read the users who have the status 'completed'.
static _getStatusInfo(int $a_obj_id)
Reads informations about the object e.g test results, tlt, number of visits.
Abstract class ilLPStatus for all learning progress modes E.g ilLPStatusManual, ilLPStatusObjectives ...
const LP_STATUS_COMPLETED_NUM
const LP_STATUS_IN_PROGRESS_NUM
const LP_STATUS_NOT_ATTEMPTED_NUM
ilObjectDataCache $ilObjDataCache
const LP_STATUS_FAILED_NUM
static getInstance(int $obj_id)
static _getAllReferences(int $id)
get all reference ids for object ID
static _lookupObjId(int $ref_id)
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
checkForParentType(int $a_ref_id, string $a_type, bool $a_exclude_source_check=false)
Check for parent type e.g check if a folder (ref_id 3) is in a parent course obj => checkForParentTyp...
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26
$counter
$objId
Definition: xapitoken.php:57