ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilLPStatus.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=0);
20
29{
30 protected int $obj_id;
31
32 protected ilDBInterface $db;
34
35 public static $list_gui_cache;
36
37 public const LP_STATUS_NOT_ATTEMPTED = 'trac_no_attempted';
38 public const LP_STATUS_IN_PROGRESS = 'trac_in_progress';
39 public const LP_STATUS_COMPLETED = 'trac_completed';
40 public const LP_STATUS_FAILED = 'trac_failed';
41
43 public const LP_STATUS_IN_PROGRESS_NUM = 1;
44 public const LP_STATUS_COMPLETED_NUM = 2;
45 public const LP_STATUS_FAILED_NUM = 3;
46
47 public const LP_STATUS_REGISTERED = 'trac_registered';
48 public const LP_STATUS_NOT_REGISTERED = 'trac_not_registered';
49 public const LP_STATUS_PARTICIPATED = 'trac_participated';
50 public const LP_STATUS_NOT_PARTICIPATED = 'trac_not_participated';
51
52 public function __construct(int $a_obj_id)
53 {
54 global $DIC;
55
56 $this->obj_id = $a_obj_id;
57 $this->db = $DIC->database();
58 $this->ilObjDataCache = $DIC['ilObjDataCache'];
59 }
60
61 public static function _getCountNotAttempted(int $a_obj_id): int
62 {
63 return 0;
64 }
65
70 public static function _getNotAttempted(int $a_obj_id): array
71 {
72 return array();
73 }
74
75 public static function _getCountInProgress(int $a_obj_id): int
76 {
77 return 0;
78 }
79
80 public static function _getInProgress(int $a_obj_id): array
81 {
82 return array();
83 }
84
85 public static function _getCountCompleted(int $a_obj_id): int
86 {
87 return 0;
88 }
89
94 public static function _getCompleted(int $a_obj_id): array
95 {
96 return array();
97 }
98
103 public static function _getFailed(int $a_obj_id): array
104 {
105 return array();
106 }
107
108 public static function _getCountFailed(int $a_obj_id): int
109 {
110 return 0;
111 }
112
113 public static function _getStatusInfo(int $a_obj_id): array
114 {
115 return array();
116 }
117
118 public static function _getTypicalLearningTime(string $type, int $obj_id, int $sub_id = 0): int
119 {
120 global $DIC;
121
122 $lom_services = $DIC->learningObjectMetadata();
123 $paths = $lom_services->paths();
124 $data_helper = $lom_services->dataHelper();
125
126 $value = $lom_services->read($obj_id, $sub_id, $type, $paths->firstTypicalLearningTime())
127 ->firstData($paths->firstTypicalLearningTime())
128 ->value();
129
130 return $data_helper->durationToSeconds($value);
131 }
132
222 public function _updateStatus(
223 int $a_obj_id,
224 int $a_usr_id,
225 ?object $a_obj = null,
226 bool $a_percentage = false,
227 bool $a_force_raise = false
228 ): void {
229 $log = ilLoggerFactory::getLogger('trac');
230 $log->debug(
231 sprintf(
232 "obj_id: %s, user id: %s, object: %s",
233 $a_obj_id,
234 $a_usr_id,
235 (is_object($a_obj) ? get_class($a_obj) : 'null')
236 )
237 );
238
239 $status = $this->determineStatus($a_obj_id, $a_usr_id, $a_obj);
240 $percentage = $this->determinePercentage($a_obj_id, $a_usr_id, $a_obj);
242 $changed = self::writeStatus(
243 $a_obj_id,
244 $a_usr_id,
245 $status,
246 $percentage,
247 false,
248 $old_status
249 );
250
251 // ak: I don't think that this is a good way to fix 15529, we should not
252 // raise the event, if the status does not change imo.
253 // for now the changes in the next line just prevent the event being raised twice
254 if (!$changed && $a_force_raise) { // #15529
256 $a_obj_id,
257 $a_usr_id,
258 $status,
259 $old_status,
260 $percentage
261 );
262 }
263 }
264
265 public function determinePercentage(
266 int $a_obj_id,
267 int $a_usr_id,
268 ?object $a_obj = null
269 ): int {
270 return 0;
271 }
272
273 public function determineStatus(
274 int $a_obj_id,
275 int $a_usr_id,
276 ?object $a_obj = null
277 ): int {
278 return 0;
279 }
280
287 public static function checkStatusForObject(
288 int $a_obj_id,
289 ?array $a_users = null
290 ): void {
291 global $DIC;
292
293 $ilDB = $DIC['ilDB'];
294
295 //@todo: there maybe the need to add extra handling for sessions here, since the
296 // "in progress" status is time dependent here. On the other hand, if they registered
297 // to the session, they already accessed the course and should have a "in progress"
298 // anyway. But the status on the session itself may not be correct.
299
300 $sql = "SELECT usr_id FROM ut_lp_marks WHERE " .
301 " obj_id = " . $ilDB->quote($a_obj_id, "integer") . " AND " .
302 " status_dirty = " . $ilDB->quote(1, "integer");
303 if (is_array($a_users) && count($a_users) > 0) {
304 $sql .= " AND " . $ilDB->in("usr_id", $a_users, false, "integer");
305 }
306 $set = $ilDB->query($sql);
307 $dirty = false;
308 if ($rec = $ilDB->fetchAssoc($set)) {
309 $dirty = true;
310 }
311
312 // check if any records are missing
313 $missing = false;
314 if (!$dirty && is_array($a_users) && count($a_users) > 0) {
315 $set = $ilDB->query(
316 "SELECT count(usr_id) cnt FROM ut_lp_marks WHERE " .
317 " obj_id = " . $ilDB->quote($a_obj_id, "integer") . " AND " .
318 $ilDB->in("usr_id", $a_users, false, "integer")
319 );
320 $r = $ilDB->fetchAssoc($set);
321 if ($r["cnt"] < count($a_users)) {
322 $missing = true;
323 }
324 }
325
326 // refresh status, if records are dirty or missing
327 if ($dirty || $missing) {
328 $trac_obj = ilLPStatusFactory::_getInstance($a_obj_id);
329 $trac_obj->refreshStatus($a_obj_id, $a_users);
330 }
331 }
332
333 protected static function raiseEvent(
334 int $a_obj_id,
335 int $a_usr_id,
336 int $a_status,
337 int $a_old_status,
338 int $a_percentage
339 ): void {
340 global $DIC;
341
342 $ilAppEventHandler = $DIC['ilAppEventHandler'];
343
345 $log->debug(
346 "obj_id: " . $a_obj_id . ", user id: " . $a_usr_id . ", status: " .
347 $a_status . ", percentage: " . $a_percentage
348 );
349
350 $ilAppEventHandler->raise(
351 "components/ILIAS/Tracking",
352 "updateStatus",
353 array(
354 "obj_id" => $a_obj_id,
355 "usr_id" => $a_usr_id,
356 "status" => $a_status,
357 "old_status" => $a_old_status,
358 "percentage" => $a_percentage
359 )
360 );
361 }
362
366 public function refreshStatus(int $a_obj_id, ?array $a_users = null): void
367 {
368 $not_attempted = ilLPStatusWrapper::_getNotAttempted($a_obj_id);
369 foreach ($not_attempted as $user_id) {
370 $percentage = $this->determinePercentage($a_obj_id, $user_id);
371 if (self::writeStatus(
372 $a_obj_id,
373 $user_id,
374 self::LP_STATUS_NOT_ATTEMPTED_NUM,
375 $percentage,
376 true
377 )) {
378 //self::raiseEvent($a_obj_id, $user_id, self::LP_STATUS_NOT_ATTEMPTED_NUM, $percentage);
379 }
380 }
381 $in_progress = ilLPStatusWrapper::_getInProgress($a_obj_id);
382 foreach ($in_progress as $user_id) {
383 $percentage = $this->determinePercentage($a_obj_id, $user_id);
384 if (self::writeStatus(
385 $a_obj_id,
386 $user_id,
387 self::LP_STATUS_IN_PROGRESS_NUM,
388 $percentage,
389 true
390 )) {
391 //self::raiseEvent($a_obj_id, $user_id, self::LP_STATUS_IN_PROGRESS_NUM, $percentage);
392 }
393 }
394 $completed = ilLPStatusWrapper::_getCompleted($a_obj_id);
395 foreach ($completed as $user_id) {
396 $percentage = $this->determinePercentage($a_obj_id, $user_id);
397 if (self::writeStatus(
398 $a_obj_id,
399 $user_id,
400 self::LP_STATUS_COMPLETED_NUM,
401 $percentage,
402 true
403 )) {
404 //self::raiseEvent($a_obj_id, $user_id, self::LP_STATUS_COMPLETED_NUM, $percentage);
405 }
406 }
407 $failed = ilLPStatusWrapper::_getFailed($a_obj_id);
408 foreach ($failed as $user_id) {
409 $percentage = $this->determinePercentage($a_obj_id, $user_id);
410 if (self::writeStatus(
411 $a_obj_id,
412 $user_id,
413 self::LP_STATUS_FAILED_NUM,
414 $percentage,
415 true
416 )) {
417 //self::raiseEvent($a_obj_id, $user_id, self::LP_STATUS_FAILED_NUM, $percentage);
418 }
419 }
420 if ($a_users) {
421 $missing_users = array_diff(
422 $a_users,
423 $not_attempted + $in_progress + $completed + $failed
424 );
425 if ($missing_users) {
426 foreach ($missing_users as $user_id) {
428 }
429 }
430 }
431 }
432
436 public static function writeStatus(
437 int $a_obj_id,
438 int $a_user_id,
439 int $a_status,
440 int $a_percentage = 0,
441 bool $a_force_per = false,
442 ?int &$a_old_status = self::LP_STATUS_NOT_ATTEMPTED_NUM
443 ): bool {
444 global $DIC;
445
446 $ilDB = $DIC->database();
447 $log = $DIC->logger()->trac();
448
449 $log->debug(
450 'Write status for: ' . "obj_id: " . $a_obj_id . ", user id: " . $a_user_id . ", status: " . $a_status . ", percentage: " . $a_percentage . ", force: " . $a_force_per
451 );
452 $update_dependencies = false;
453
454 $a_old_status = self::LP_STATUS_NOT_ATTEMPTED_NUM;
455
456 // get status in DB
457 $set = $ilDB->query(
458 "SELECT usr_id,status,status_dirty FROM ut_lp_marks WHERE " .
459 " obj_id = " . $ilDB->quote($a_obj_id, "integer") . " AND " .
460 " usr_id = " . $ilDB->quote($a_user_id, "integer")
461 );
462 $rec = $ilDB->fetchAssoc($set);
463
464 // update
465 if ($rec) {
466 $a_old_status = $rec["status"];
467
468 // status has changed: update
469 if ($rec["status"] != $a_status) {
470 $ret = $ilDB->manipulate(
471 "UPDATE ut_lp_marks SET " .
472 " status = " . $ilDB->quote($a_status, "integer") . "," .
473 " status_changed = " . $ilDB->now() . "," .
474 " status_dirty = " . $ilDB->quote(0, "integer") .
475 " WHERE usr_id = " . $ilDB->quote($a_user_id, "integer") .
476 " AND obj_id = " . $ilDB->quote($a_obj_id, "integer")
477 );
478 if ($ret != 0) {
479 $update_dependencies = true;
480 }
481 } // status has not changed: reset dirty flag
482 elseif ($rec["status_dirty"]) {
483 $ilDB->manipulate(
484 "UPDATE ut_lp_marks SET " .
485 " status_dirty = " . $ilDB->quote(0, "integer") .
486 " WHERE usr_id = " . $ilDB->quote($a_user_id, "integer") .
487 " AND obj_id = " . $ilDB->quote($a_obj_id, "integer")
488 );
489 }
490 } // insert
491 else {
492 // #13783
493 $ilDB->replace(
494 "ut_lp_marks",
495 array(
496 "obj_id" => array("integer", $a_obj_id),
497 "usr_id" => array("integer", $a_user_id)
498 ),
499 array(
500 "status" => array("integer", $a_status),
501 "status_changed" => array("timestamp", date("Y-m-d H:i:s")),
502 // was $ilDB->now()
503 "status_dirty" => array("integer", 0)
504 )
505 );
506
507 $update_dependencies = true;
508 }
509
510 // update percentage
511 if ($a_percentage || $a_force_per) {
512 $a_percentage = max(0, $a_percentage);
513 $a_percentage = min(100, $a_percentage);
514 $ret = $ilDB->manipulate(
515 "UPDATE ut_lp_marks SET " .
516 " percentage = " . $ilDB->quote($a_percentage, "integer") .
517 " WHERE usr_id = " . $ilDB->quote($a_user_id, "integer") .
518 " AND obj_id = " . $ilDB->quote($a_obj_id, "integer")
519 );
520 }
521
522 $log->debug(
523 'Update dependecies is ' . ($update_dependencies ? 'true' : 'false')
524 );
525
526 // update collections
527 if ($update_dependencies) {
528 $log->debug('update dependencies');
529
530 // a change occured - remove existing cache entry
531 ilLPStatusWrapper::_removeStatusCache($a_obj_id, $a_user_id);
532
533 $set = $ilDB->query(
534 "SELECT ut_lp_collections.obj_id obj_id FROM " .
535 "object_reference JOIN ut_lp_collections ON " .
536 "(object_reference.obj_id = " . $ilDB->quote(
537 $a_obj_id,
538 "integer"
539 ) .
540 " AND object_reference.ref_id = ut_lp_collections.item_id)"
541 );
542 while ($rec = $ilDB->fetchAssoc($set)) {
543 if (in_array(
544 ilObject::_lookupType($rec["obj_id"]),
545 array("crs", "grp", "fold")
546 )) {
547 $log->debug(
548 'Calling update status for collection obj_id: ' . $rec['obj_id']
549 );
550 // just to make sure - remove existing cache entry
552 (int) $rec["obj_id"],
553 $a_user_id
554 );
556 (int) $rec["obj_id"],
557 $a_user_id
558 );
559 }
560 }
561
562 // find all course references
563 if (ilObject::_lookupType($a_obj_id) == 'crs') {
564 $log->debug('update references');
565
566 $query = 'select obj_id from container_reference ' .
567 'where target_obj_id = ' . $ilDB->quote(
568 $a_obj_id,
570 );
571 $res = $ilDB->query($query);
572 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
573 $log->debug(
574 'Calling update status for reference obj_id: ' . $row->obj_id
575 );
577 (int) $row->obj_id,
578 $a_user_id
579 );
581 (int) $row->obj_id,
582 $a_user_id
583 );
584 }
585 }
586
587 self::raiseEvent(
588 $a_obj_id,
589 $a_user_id,
590 $a_status,
591 $a_old_status,
592 $a_percentage
593 );
594 }
595
596 return $update_dependencies;
597 }
598
604 public static function setInProgressIfNotAttempted(
605 int $a_obj_id,
606 int $a_user_id
607 ): void {
608 global $DIC;
609
610 $ilDB = $DIC['ilDB'];
611
612 // #11513
613
614 $needs_update = false;
615
616 $set = $ilDB->query(
617 "SELECT usr_id, status FROM ut_lp_marks WHERE " .
618 " obj_id = " . $ilDB->quote($a_obj_id, "integer") . " AND " .
619 " usr_id = " . $ilDB->quote($a_user_id, "integer")
620 );
621 if ($rec = $ilDB->fetchAssoc($set)) {
622 // current status is not attempted, so we need to update
623 if ($rec["status"] == self::LP_STATUS_NOT_ATTEMPTED_NUM) {
624 $needs_update = true;
625 }
626 } else {
627 // no ut_lp_marks yet, we should update
628 $needs_update = true;
629 }
630
631 if ($needs_update) {
632 ilLPStatusWrapper::_updateStatus($a_obj_id, $a_user_id);
633 }
634 }
635
639 public static function setAllDirty(): void
640 {
641 global $DIC;
642
643 $ilDB = $DIC['ilDB'];
644
645 $ilDB->manipulate(
646 "UPDATE ut_lp_marks SET " .
647 " status_dirty = " . $ilDB->quote(1, "integer")
648 );
649 }
650
654 public static function setDirty(int $a_obj_id): void
655 {
656 global $DIC;
657
658 $ilDB = $DIC['ilDB'];
659
660 $ilDB->manipulate(
661 "UPDATE ut_lp_marks SET " .
662 " status_dirty = " . $ilDB->quote(1, "integer") .
663 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer")
664 );
665 }
666
670 public static function _lookupStatus(
671 int $a_obj_id,
672 int $a_user_id,
673 bool $a_create = true
674 ): ?int {
675 global $DIC;
676
677 $ilDB = $DIC['ilDB'];
678
679 $set = $ilDB->query(
680 "SELECT status FROM ut_lp_marks WHERE " .
681 " status_dirty = " . $ilDB->quote(0, "integer") .
682 " AND usr_id = " . $ilDB->quote($a_user_id, "integer") .
683 " AND obj_id = " . $ilDB->quote($a_obj_id, "integer")
684 );
685 if ($rec = $ilDB->fetchAssoc($set)) {
686 return (int) $rec["status"];
687 } elseif ($a_create) {
688 ilLPStatusWrapper::_updateStatus($a_obj_id, $a_user_id);
689 $set = $ilDB->query(
690 "SELECT status FROM ut_lp_marks WHERE " .
691 " status_dirty = " . $ilDB->quote(0, "integer") .
692 " AND usr_id = " . $ilDB->quote($a_user_id, "integer") .
693 " AND obj_id = " . $ilDB->quote($a_obj_id, "integer")
694 );
695 if ($rec = $ilDB->fetchAssoc($set)) {
696 return (int) $rec["status"];
697 }
698 }
699 return null;
700 }
701
705 public static function _lookupPercentage(
706 int $a_obj_id,
707 int $a_user_id
708 ): ?int {
709 global $DIC;
710
711 $ilDB = $DIC['ilDB'];
712
713 $set = $ilDB->query(
714 "SELECT percentage FROM ut_lp_marks WHERE " .
715 " status_dirty = " . $ilDB->quote(0, "integer") .
716 " AND usr_id = " . $ilDB->quote($a_user_id, "integer") .
717 " AND obj_id = " . $ilDB->quote($a_obj_id, "integer")
718 );
719 if ($rec = $ilDB->fetchAssoc($set)) {
720 return $rec["percentage"];
721 }
722 return null;
723 }
724
728 public static function _hasUserCompleted(
729 int $a_obj_id,
730 int $a_user_id
731 ): bool {
732 return self::_lookupStatus(
733 $a_obj_id,
734 $a_user_id
735 ) == self::LP_STATUS_COMPLETED_NUM;
736 }
737
741 public static function _lookupStatusChanged(
742 int $a_obj_id,
743 int $a_user_id
744 ): ?string {
745 global $DIC;
746
747 $ilDB = $DIC['ilDB'];
748
749 $set = $ilDB->query(
750 "SELECT status_changed FROM ut_lp_marks WHERE " .
751 " status_dirty = " . $ilDB->quote(0, "integer") .
752 " AND usr_id = " . $ilDB->quote($a_user_id, "integer") .
753 " AND obj_id = " . $ilDB->quote($a_obj_id, "integer")
754 );
755 if ($rec = $ilDB->fetchAssoc($set)) {
756 return (string) $rec["status_changed"];
757 } else {
758 ilLPStatusWrapper::_updateStatus($a_obj_id, $a_user_id);
759 $set = $ilDB->query(
760 "SELECT status_changed FROM ut_lp_marks WHERE " .
761 " status_dirty = " . $ilDB->quote(0, "integer") .
762 " AND usr_id = " . $ilDB->quote($a_user_id, "integer") .
763 " AND obj_id = " . $ilDB->quote($a_obj_id, "integer")
764 );
765 if ($rec = $ilDB->fetchAssoc($set)) {
766 return (string) $rec["status_changed"];
767 }
768 }
769 return null;
770 }
771
775 protected static function _lookupStatusForObject(
776 int $a_obj_id,
777 int $a_status,
778 ?array $a_user_ids = null
779 ): array {
780 global $DIC;
781
782 $ilDB = $DIC['ilDB'];
783
784 $sql = "SELECT usr_id, status, status_dirty FROM ut_lp_marks" .
785 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer") .
786 " AND status = " . $ilDB->quote($a_status, "integer");
787 if ($a_user_ids) {
788 $sql .= " AND " . $ilDB->in("usr_id", $a_user_ids, "", "integer");
789 }
790
791 $set = $ilDB->query($sql);
792 $res = array();
793 while ($rec = $ilDB->fetchAssoc($set)) {
794 // @fixme this was broken due to wrong $res['status_dirty'] access
795 // check how to update status without recursion
796 // check consequences of the old implementation
797 if ($rec["status_dirty"]) {
798 // update status and check again
799 if (self::_lookupStatus(
800 $a_obj_id,
801 $rec["usr_id"]
802 ) != $a_status) {
803 // update status: see comment
804 }
805 }
806 $res[] = (int) $rec["usr_id"];
807 }
808
809 return $res;
810 }
811
815 public static function _lookupCompletedForObject(
816 int $a_obj_id,
817 ?array $a_user_ids = null
818 ): array {
819 return self::_lookupStatusForObject(
820 $a_obj_id,
821 self::LP_STATUS_COMPLETED_NUM,
822 $a_user_ids
823 );
824 }
825
829 public static function _lookupFailedForObject(
830 int $a_obj_id,
831 ?array $a_user_ids = null
832 ): array {
833 return self::_lookupStatusForObject(
834 $a_obj_id,
835 self::LP_STATUS_FAILED_NUM,
836 $a_user_ids
837 );
838 }
839
843 public static function _lookupInProgressForObject(
844 int $a_obj_id,
845 ?array $a_user_ids = null
846 ): array {
847 return self::_lookupStatusForObject(
848 $a_obj_id,
849 self::LP_STATUS_IN_PROGRESS_NUM,
850 $a_user_ids
851 );
852 }
853
857 protected static function validateLPForObjects(
858 int $a_user_id,
859 array $a_obj_ids,
860 int $a_parent_ref_id
861 ): array {
862 $lp_invalid = array();
863
864 $memberships = ilObjectLP::getLPMemberships(
865 $a_user_id,
866 $a_obj_ids,
867 $a_parent_ref_id
868 );
869 foreach ($memberships as $obj_id => $status) {
870 if (!$status) {
871 $lp_invalid[] = $obj_id;
872 }
873 }
874
875 return array_diff($a_obj_ids, $lp_invalid);
876 }
877
881 protected static function checkLPModesForObjects(
882 array $a_obj_ids,
883 array &$a_coll_obj_ids
884 ): array {
885 $valid = array();
886
887 // all lp modes with collections (gathered separately)
889
890 // check if objects have LP activated at all (DB entries)
891 $existing = ilLPObjSettings::_lookupDBModeForObjects($a_obj_ids);
892 foreach ($existing as $obj_id => $obj_mode) {
893 if ($obj_mode != ilLPObjSettings::LP_MODE_DEACTIVATED) {
894 $valid[$obj_id] = $obj_id;
895
896 if (in_array($obj_mode, $coll_modes)) {
897 $a_coll_obj_ids[] = $obj_id;
898 }
899 }
900 }
901
902 // missing objects in DB (default mode)
903 $existing_obj_ids = array_keys($existing);
904 if (sizeof($existing) != sizeof($a_obj_ids)) {
905 foreach (array_diff($a_obj_ids, $existing_obj_ids) as $obj_id) {
906 $olp = ilObjectLP::getInstance($obj_id);
907 $mode = $olp->getCurrentMode();
909 // #11141
910 unset($valid[$obj_id]);
911 } elseif ($mode != ilLPObjSettings::LP_MODE_UNDEFINED) {
912 $valid[$obj_id] = $obj_id;
913
914 if (in_array($mode, $coll_modes)) {
915 $a_coll_obj_ids[] = $obj_id;
916 }
917 }
918 }
919 unset($existing);
920 }
921 return array_values($valid);
922 }
923
927 protected static function getLPStatusForObjects(
928 int $a_user_id,
929 array $a_obj_ids
930 ): array {
931 global $DIC;
932
933 $ilDB = $DIC['ilDB'];
934
935 $res = array();
936
937 // get user lp data
938 $sql = "SELECT status, status_dirty, obj_id FROM ut_lp_marks" .
939 " WHERE " . $ilDB->in("obj_id", $a_obj_ids, "", "integer") .
940 " AND usr_id = " . $ilDB->quote($a_user_id, "integer");
941 $set = $ilDB->query($sql);
942 while ($row = $ilDB->fetchAssoc($set)) {
943 if (!$row["status_dirty"]) {
944 $res[$row["obj_id"]] = $row["status"];
945 } else {
946 $res[$row["obj_id"]] = self::_lookupStatus(
947 $row["obj_id"],
948 $a_user_id
949 );
950 }
951 }
952
953 // process missing user entries (same as dirty entries, see above)
954 foreach ($a_obj_ids as $obj_id) {
955 if (!isset($res[$obj_id])) {
956 $res[$obj_id] = self::_lookupStatus($obj_id, $a_user_id);
957 if ($res[$obj_id] === null) {
958 $res[$obj_id] = self::LP_STATUS_NOT_ATTEMPTED_NUM;
959 }
960 }
961 }
962
963 return $res;
964 }
965
966 public static function preloadListGUIData(array $a_obj_ids): void
967 {
968 global $DIC;
969
971 if ($DIC->http()->wrapper()->query()->has('ref_id')) {
972 $requested_ref_id = $DIC->http()->wrapper()->query()->retrieve(
973 'ref_id',
974 $DIC->refinery()->kindlyTo()->int()
975 );
976 }
977
978 $ilUser = $DIC['ilUser'];
979 $lng = $DIC['lng'];
980
981 $user_id = $ilUser->getId();
982 $res = array();
983 if ($ilUser->getId() != ANONYMOUS_USER_ID &&
987 // -- validate
988
989 // :TODO: we need the parent ref id, but this is awful
990 // this step removes all "not attempted" from the list, which we usually do not want
991 //$a_obj_ids = self::validateLPForObjects($user_id, $a_obj_ids, $requested_ref_id);
992
993 // we are not handling the collections differently yet
994 $coll_obj_ids = array();
995 $a_obj_ids = self::checkLPModesForObjects(
996 $a_obj_ids,
997 $coll_obj_ids
998 );
999
1000 // -- gather
1001
1002 $res = self::getLPStatusForObjects($user_id, $a_obj_ids);
1003
1004 // -- render
1005
1006 // value to icon
1007 $lng->loadLanguageModule("trac");
1009 foreach ($res as $obj_id => $status) {
1010 $res[$obj_id] = [
1011 "image" => $icons->renderIconForStatus($status),
1012 "status" => $status
1013 ];
1014 }
1015 }
1016
1017 self::$list_gui_cache = $res;
1018 }
1019
1023 public static function getListGUIStatus(
1024 int $a_obj_id,
1025 bool $a_image_only = true
1026 ) {
1027 if ($a_image_only) {
1028 $image = '';
1029 if (isset(self::$list_gui_cache[$a_obj_id]["image"])) {
1030 $image = self::$list_gui_cache[$a_obj_id]["image"];
1031 }
1032
1033 return $image;
1034 }
1035 return self::$list_gui_cache[$a_obj_id] ?? "";
1036 }
1037
1038 public static function hasListGUIStatus(int $a_obj_id): bool
1039 {
1040 if (isset(self::$list_gui_cache[$a_obj_id])) {
1041 return true;
1042 }
1043 return false;
1044 }
1045}
static _lookupDBModeForObjects(array $a_obj_ids)
static _getInstance(int $a_obj_id, ?int $a_mode=null)
static getInstance(int $variant=ilLPStatusIcons::ICON_VARIANT_DEFAULT, ?\ILIAS\UI\Renderer $renderer=null, ?\ILIAS\UI\Factory $factory=null)
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 _removeStatusCache(int $a_obj_id, int $a_usr_id)
static _getNotAttempted(int $a_obj_id)
Static function to read the number of user who have the status 'not_attempted'.
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
static _getCompleted(int $a_obj_id)
Static function to read the users who have the status 'completed'.
Abstract class ilLPStatus for all learning progress modes E.g ilLPStatusManual, ilLPStatusObjectives ...
static writeStatus(int $a_obj_id, int $a_user_id, int $a_status, int $a_percentage=0, bool $a_force_per=false, ?int &$a_old_status=self::LP_STATUS_NOT_ATTEMPTED_NUM)
Write status for user and object.
static validateLPForObjects(int $a_user_id, array $a_obj_ids, int $a_parent_ref_id)
Process given objects for lp-relevance.
static preloadListGUIData(array $a_obj_ids)
const LP_STATUS_COMPLETED_NUM
static _lookupPercentage(int $a_obj_id, int $a_user_id)
Lookup percentage.
static setDirty(int $a_obj_id)
Sets status of an object to dirty.
determineStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null)
const LP_STATUS_NOT_PARTICIPATED
static _getInProgress(int $a_obj_id)
static _hasUserCompleted(int $a_obj_id, int $a_user_id)
Lookup user object completion.
static getListGUIStatus(int $a_obj_id, bool $a_image_only=true)
static _lookupCompletedForObject(int $a_obj_id, ?array $a_user_ids=null)
Get completed users for object.
__construct(int $a_obj_id)
static setInProgressIfNotAttempted(int $a_obj_id, int $a_user_id)
This function shoudl be clalled for normal "read events".
const LP_STATUS_COMPLETED
determinePercentage(int $a_obj_id, int $a_usr_id, ?object $a_obj=null)
static _getFailed(int $a_obj_id)
const LP_STATUS_NOT_REGISTERED
const LP_STATUS_PARTICIPATED
const LP_STATUS_FAILED
static _lookupStatusChanged(int $a_obj_id, int $a_user_id)
Lookup status changed.
const LP_STATUS_IN_PROGRESS_NUM
static _lookupInProgressForObject(int $a_obj_id, ?array $a_user_ids=null)
Get in progress users for object.
ilDBInterface $db
_updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
New status handling (st: status, nr: accesses, p: percentage, t: time spent, m: mark) Learning progre...
static checkLPModesForObjects(array $a_obj_ids, array &$a_coll_obj_ids)
Process lp modes for given objects.
static _getCountCompleted(int $a_obj_id)
static _getNotAttempted(int $a_obj_id)
static raiseEvent(int $a_obj_id, int $a_usr_id, int $a_status, int $a_old_status, int $a_percentage)
const LP_STATUS_NOT_ATTEMPTED_NUM
const LP_STATUS_REGISTERED
static _getCountNotAttempted(int $a_obj_id)
ilObjectDataCache $ilObjDataCache
static _getCountInProgress(int $a_obj_id)
static _lookupFailedForObject(int $a_obj_id, ?array $a_user_ids=null)
Get failed users for object.
static _lookupStatus(int $a_obj_id, int $a_user_id, bool $a_create=true)
Lookup status.
static setAllDirty()
Sets all status to dirty.
static $list_gui_cache
refreshStatus(int $a_obj_id, ?array $a_users=null)
Refresh status.
static getLPStatusForObjects(int $a_user_id, array $a_obj_ids)
Get LP status for given objects (and user)
static _getCompleted(int $a_obj_id)
static checkStatusForObject(int $a_obj_id, ?array $a_users=null)
This function checks whether the status for a given number of users is dirty and must be recalculated...
const LP_STATUS_FAILED_NUM
static _lookupStatusForObject(int $a_obj_id, int $a_status, ?array $a_user_ids=null)
Get users with given status for object.
static _getTypicalLearningTime(string $type, int $obj_id, int $sub_id=0)
static _getStatusInfo(int $a_obj_id)
const LP_STATUS_NOT_ATTEMPTED
const LP_STATUS_IN_PROGRESS
static hasListGUIStatus(int $a_obj_id)
static _getCountFailed(int $a_obj_id)
static getLogger(string $a_component_id)
Get component logger.
class ilObjectDataCache
static getLPMemberships(int $usr_id, array $obj_ids, ?int $parent_ref_id=null, bool $mapped_ref_ids=false)
Get all objects where given user is member (from LP POV)
static getInstance(int $obj_id)
static _lookupType(int $id, bool $reference=false)
const ANONYMOUS_USER_ID
Definition: constants.php:27
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$valid
$requested_ref_id
Definition: feed.php:40
Interface ilDBInterface.
$log
Definition: ltiresult.php:34
$res
Definition: ltiservices.php:69
global $lng
Definition: privfeed.php:31
global $DIC
Definition: shib_login.php:26