ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilLPStatusCollection.php
Go to the documentation of this file.
1 <?php
2 
19 declare(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(int $a_obj_id): int
247  {
248  global $DIC;
249 
250  $ilObjDataCache = $DIC['ilObjDataCache'];
251 
252  if ($ilObjDataCache->lookupType($a_obj_id) == 'sahs') {
253  return parent::_getTypicalLearningTime($a_obj_id);
254  }
255 
256  $tlt = 0;
257  $status_info = ilLPStatusWrapper::_getStatusInfo($a_obj_id);
258  foreach ($status_info['collections'] as $item) {
260  $ilObjDataCache->lookupObjId((int) $item)
261  );
262  }
263  return $tlt;
264  }
265 
266  public function determineStatus(
267  int $a_obj_id,
268  int $a_usr_id,
269  object $a_obj = null
270  ): int {
271  global $DIC;
272 
273  $ilObjDataCache = $DIC['ilObjDataCache'];
274 
275  $status['completed'] = true;
276  $status['failed'] = false;
277  $status['in_progress'] = false;
278 
279  switch ($this->ilObjDataCache->lookupType($a_obj_id)) {
280  case "crs":
281  case "fold":
282  case "grp":
283  case "lso":
284  if (ilChangeEvent::hasAccessed($a_obj_id, $a_usr_id)) {
285  $status['in_progress'] = true;
286  }
287 
288  $olp = ilObjectLP::getInstance($a_obj_id);
289  $collection = $olp->getCollectionInstance();
290  $grouped_items = [];
291  if ($collection) {
292  $grouped_items = $collection->getGroupedItemsForLPStatus();
293  }
294  if (!count($grouped_items)) {
295  // #11513 - empty collections cannot be completed
296  $status['completed'] = false;
297  } else {
298  foreach ($grouped_items as $grouping_id => $grouping) {
299  $isGrouping = $grouping_id ? true : false;
300  $status = self::determineGroupingStatus(
301  $status,
302  $grouping,
303  $a_usr_id,
304  $isGrouping
305  );
306  }
307  }
308 
309  if ($status['completed']) {
310  if (!$this->isMember((int) $a_obj_id, (int) $a_usr_id)) {
311  return self::LP_STATUS_IN_PROGRESS_NUM;
312  }
313 
314  return self::LP_STATUS_COMPLETED_NUM;
315  }
316 
317  if ($status['failed']) {
318  return self::LP_STATUS_FAILED_NUM;
319  }
320 
321  if ($status['in_progress']) {
322  return self::LP_STATUS_IN_PROGRESS_NUM;
323  }
324  break;
325  }
326  return self::LP_STATUS_NOT_ATTEMPTED_NUM;
327  }
328 
332  public static function determineGroupingStatus(
333  array $status,
334  array $gr_info,
335  int $user_id,
336  bool $is_grouping
337  ): array {
338  global $DIC;
339 
340  $ilObjDataCache = $DIC['ilObjDataCache'];
341 
342  $items = $gr_info['items'];
343  if ($is_grouping) {
344  $max_allowed_failed = count($items) - $gr_info['num_obligatory'];
345  $required_completed = $gr_info['num_obligatory'];
346  } else {
347  $max_allowed_failed = 0;
348  $required_completed = count($items);
349  }
350 
351  // Required for grouping with a number of obligatory items
352  $num_failed = 0;
353  $num_completed = 0;
354 
355  foreach ($items as $item_id) {
356  $item_id = $ilObjDataCache->lookupObjId((int) $item_id);
358  $item_id,
359  $user_id
360  );
361 
362  if ($gr_status == self::LP_STATUS_FAILED_NUM) {
363  if (++$num_failed > $max_allowed_failed) {
364  $status['failed'] = true;
365  $status['completed'] = false;
366  return $status;
367  }
368  }
369  if ($gr_status == self::LP_STATUS_COMPLETED_NUM) {
370  if (++$num_completed >= $required_completed) {
371  return $status;
372  }
373  }
374  }
375  // Not completed since returned above
376  $status['completed'] = false;
377  return $status;
378  }
379 
385  protected function isMember(int $objId, int $usrId): bool
386  {
387  switch ($this->ilObjDataCache->lookupType($objId)) {
388  case 'crs':
389  $participants = ilCourseParticipant::_getInstanceByObjId($objId, $usrId);
390  return $participants->isMember();
391 
392  case 'grp':
393  $participants = ilGroupParticipants::_getInstanceByObjId($objId);
394  return $participants->isMember($usrId);
395 
396  case 'fold':
397  $folderRefIds = ilObject::_getAllReferences($objId);
398  $folderRefId = current($folderRefIds);
399  if ($crsRefId = $this->tree->checkForParentType($folderRefId, 'crs')) {
400  $participants = ilCourseParticipant::_getInstanceByObjId(ilObject::_lookupObjId($crsRefId), $usrId);
401  return $participants->isMember();
402  }
403 
404  if ($grpRefId = $this->tree->checkForParentType($folderRefId, 'grp')) {
406  return $participants->isMember($usrId);
407  }
408  break;
409 
410  case 'lso':
412  return $participants->isMember($usrId);
413  }
414 
415  return true;
416  }
417 
423  protected static function getMembers(int $a_obj_id): array
424  {
425  global $DIC;
426 
427  $ilObjDataCache = $DIC['ilObjDataCache'];
428  $tree = $DIC['tree'];
429 
430  switch ($ilObjDataCache->lookupType($a_obj_id)) {
431  case 'crs':
433  $a_obj_id
434  );
435  return $member_obj->getMembers();
436 
437  case 'grp':
439  $a_obj_id
440  );
441  return $member_obj->getMembers();
442 
443  case 'fold':
444  $folder_ref_ids = ilObject::_getAllReferences($a_obj_id);
445  $folder_ref_id = current($folder_ref_ids);
446  if ($crs_id = $tree->checkForParentType(
447  $folder_ref_id,
448  'crs'
449  )) {
451  ilObject::_lookupObjId($crs_id)
452  );
453  return $member_obj->getMembers();
454  }
455  break;
456 
457  case 'lso':
459  $a_obj_id
460  );
461  return $member_obj->getMembers();
462  break;
463  }
464 
465  return array();
466  }
467 
471  public static function _lookupCompletedForObject(
472  int $a_obj_id,
473  ?array $a_user_ids = null
474  ): array {
475  if (!$a_user_ids) {
476  $a_user_ids = self::getMembers($a_obj_id);
477  if (!$a_user_ids) {
478  return array();
479  }
480  }
481  return self::_lookupStatusForObject(
482  $a_obj_id,
483  self::LP_STATUS_COMPLETED_NUM,
484  $a_user_ids
485  );
486  }
487 
491  public static function _lookupFailedForObject(
492  int $a_obj_id,
493  ?array $a_user_ids = null
494  ): array {
495  if (!$a_user_ids) {
496  $a_user_ids = self::getMembers($a_obj_id);
497  if (!$a_user_ids) {
498  return array();
499  }
500  }
501  return self::_lookupStatusForObject(
502  $a_obj_id,
503  self::LP_STATUS_FAILED_NUM,
504  $a_user_ids
505  );
506  }
507 
511  public static function _lookupInProgressForObject(
512  int $a_obj_id,
513  ?array $a_user_ids = null
514  ): array {
515  if (!$a_user_ids) {
516  $a_user_ids = self::getMembers($a_obj_id);
517  if (!$a_user_ids) {
518  return array();
519  }
520  }
521  return self::_lookupStatusForObject(
522  $a_obj_id,
523  self::LP_STATUS_IN_PROGRESS_NUM,
524  $a_user_ids
525  );
526  }
527 }
static _getFailed(int $a_obj_id)
static _getCompleted(int $a_obj_id)
Static function to read the users who have the status &#39;completed&#39;.
determineStatus(int $a_obj_id, int $a_usr_id, object $a_obj=null)
static _getStatusInfo(int $a_obj_id)
Reads informations about the object e.g test results, tlt, number of visits.
static _getInstanceByObjId(int $a_obj_id, int $a_usr_id)
static _getAllReferences(int $id)
get all reference ids for object ID
static _getCompleted(int $a_obj_id)
Get completed users New handling for optional grouped assignments.
static hasAccessed(int $a_obj_id, int $a_usr_id)
Has accessed.
static _getTypicalLearningTime(int $a_obj_id)
$objId
Definition: xapitoken.php:57
isMember(int $objId, int $usrId)
static _getInProgress(int $a_obj_id)
Static function to read users who have the status &#39;in_progress&#39;.
static _getStatusInfo(int $a_obj_id)
static _lookupObjId(int $ref_id)
global $DIC
Definition: feed.php:28
static lookupUsersInProgress(int $a_obj_id)
static determineGroupingStatus(array $status, array $gr_info, int $user_id, bool $is_grouping)
Determine grouping status.
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(VocabulariesInterface $vocabularies)
static _getInstanceByObjId(int $a_obj_id)
static _getFailed(int $a_obj_id)
Static function to read the users who have the status &#39;completed&#39;.
static getMembers(int $a_obj_id)
Get members for object.
static _getTypicalLearningTime(int $a_obj_id)
Reads Typical learning time.
ilObjectDataCache $ilObjDataCache
static _lookupCompletedForObject(int $a_obj_id, ?array $a_user_ids=null)
Get completed users for object.
static _getInProgress(int $a_obj_id)
static _lookupInProgressForObject(int $a_obj_id, ?array $a_user_ids=null)
Get in progress users for object.
static _getInstanceByObjId(int $a_obj_id)
Get singleton instance.
static _determineStatus(int $a_obj_id, int $a_usr_id)
static _lookupFailedForObject(int $a_obj_id, ?array $a_user_ids=null)
Get failed users for object.
static getInstance(int $obj_id)
static _getNotAttempted(int $a_obj_id)