19declare(strict_types=0);
56 $this->obj_id = $a_obj_id;
57 $this->db =
$DIC->database();
58 $this->ilObjDataCache =
$DIC[
'ilObjDataCache'];
122 $lom_services =
$DIC->learningObjectMetadata();
123 $paths = $lom_services->paths();
124 $data_helper = $lom_services->dataHelper();
126 $value = $lom_services->read(
$obj_id, $sub_id, $type, $paths->firstTypicalLearningTime())
127 ->firstData($paths->firstTypicalLearningTime())
130 return $data_helper->durationToSeconds($value);
225 ?
object $a_obj =
null,
226 bool $a_percentage =
false,
227 bool $a_force_raise =
false
232 "obj_id: %s, user id: %s, object: %s",
235 (is_object($a_obj) ? get_class($a_obj) :
'null')
254 if (!$changed && $a_force_raise) {
268 ?
object $a_obj =
null
276 ?
object $a_obj =
null
289 ?array $a_users =
null
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");
306 $set =
$ilDB->query($sql);
308 if ($rec =
$ilDB->fetchAssoc($set)) {
314 if (!$dirty && is_array($a_users) && count($a_users) > 0) {
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")
320 $r =
$ilDB->fetchAssoc($set);
321 if ($r[
"cnt"] < count($a_users)) {
327 if ($dirty || $missing) {
329 $trac_obj->refreshStatus($a_obj_id, $a_users);
342 $ilAppEventHandler =
$DIC[
'ilAppEventHandler'];
346 "obj_id: " . $a_obj_id .
", user id: " . $a_usr_id .
", status: " .
347 $a_status .
", percentage: " . $a_percentage
350 $ilAppEventHandler->raise(
351 "components/ILIAS/Tracking",
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
369 foreach ($not_attempted as
$user_id) {
370 $percentage = $this->determinePercentage($a_obj_id,
$user_id);
371 if (self::writeStatus(
374 self::LP_STATUS_NOT_ATTEMPTED_NUM,
382 foreach ($in_progress as
$user_id) {
383 $percentage = $this->determinePercentage($a_obj_id,
$user_id);
384 if (self::writeStatus(
387 self::LP_STATUS_IN_PROGRESS_NUM,
396 $percentage = $this->determinePercentage($a_obj_id,
$user_id);
397 if (self::writeStatus(
400 self::LP_STATUS_COMPLETED_NUM,
409 $percentage = $this->determinePercentage($a_obj_id,
$user_id);
410 if (self::writeStatus(
413 self::LP_STATUS_FAILED_NUM,
421 $missing_users = array_diff(
423 $not_attempted + $in_progress + $completed + $failed
425 if ($missing_users) {
426 foreach ($missing_users as
$user_id) {
440 int $a_percentage = 0,
441 bool $a_force_per =
false,
442 ?
int &$a_old_status = self::LP_STATUS_NOT_ATTEMPTED_NUM
450 'Write status for: ' .
"obj_id: " . $a_obj_id .
", user id: " . $a_user_id .
", status: " . $a_status .
", percentage: " . $a_percentage .
", force: " . $a_force_per
452 $update_dependencies =
false;
454 $a_old_status = self::LP_STATUS_NOT_ATTEMPTED_NUM;
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")
462 $rec =
$ilDB->fetchAssoc($set);
466 $a_old_status = $rec[
"status"];
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")
479 $update_dependencies =
true;
482 elseif ($rec[
"status_dirty"]) {
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")
496 "obj_id" => array(
"integer", $a_obj_id),
497 "usr_id" => array(
"integer", $a_user_id)
500 "status" => array(
"integer", $a_status),
501 "status_changed" => array(
"timestamp", date(
"Y-m-d H:i:s")),
503 "status_dirty" => array(
"integer", 0)
507 $update_dependencies =
true;
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")
523 'Update dependecies is ' . ($update_dependencies ?
'true' :
'false')
527 if ($update_dependencies) {
528 $log->debug(
'update dependencies');
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(
540 " AND object_reference.ref_id = ut_lp_collections.item_id)"
542 while ($rec =
$ilDB->fetchAssoc($set)) {
545 array(
"crs",
"grp",
"fold")
548 'Calling update status for collection obj_id: ' . $rec[
'obj_id']
552 (
int) $rec[
"obj_id"],
556 (
int) $rec[
"obj_id"],
564 $log->debug(
'update references');
566 $query =
'select obj_id from container_reference ' .
567 'where target_obj_id = ' .
$ilDB->quote(
574 'Calling update status for reference obj_id: ' . $row->obj_id
596 return $update_dependencies;
614 $needs_update =
false;
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")
621 if ($rec =
$ilDB->fetchAssoc($set)) {
623 if ($rec[
"status"] == self::LP_STATUS_NOT_ATTEMPTED_NUM) {
624 $needs_update =
true;
628 $needs_update =
true;
646 "UPDATE ut_lp_marks SET " .
647 " status_dirty = " .
$ilDB->quote(1,
"integer")
654 public static function setDirty(
int $a_obj_id): void
661 "UPDATE ut_lp_marks SET " .
662 " status_dirty = " .
$ilDB->quote(1,
"integer") .
663 " WHERE obj_id = " .
$ilDB->quote($a_obj_id,
"integer")
673 bool $a_create =
true
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")
685 if ($rec =
$ilDB->fetchAssoc($set)) {
686 return (
int) $rec[
"status"];
687 } elseif ($a_create) {
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")
695 if ($rec =
$ilDB->fetchAssoc($set)) {
696 return (
int) $rec[
"status"];
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")
719 if ($rec =
$ilDB->fetchAssoc($set)) {
720 return $rec[
"percentage"];
732 return self::_lookupStatus(
735 ) == self::LP_STATUS_COMPLETED_NUM;
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")
755 if ($rec =
$ilDB->fetchAssoc($set)) {
756 return (
string) $rec[
"status_changed"];
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")
765 if ($rec =
$ilDB->fetchAssoc($set)) {
766 return (
string) $rec[
"status_changed"];
778 ?array $a_user_ids =
null
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");
788 $sql .=
" AND " .
$ilDB->in(
"usr_id", $a_user_ids,
"",
"integer");
791 $set =
$ilDB->query($sql);
793 while ($rec =
$ilDB->fetchAssoc($set)) {
797 if ($rec[
"status_dirty"]) {
799 if (self::_lookupStatus(
817 ?array $a_user_ids =
null
819 return self::_lookupStatusForObject(
821 self::LP_STATUS_COMPLETED_NUM,
831 ?array $a_user_ids =
null
833 return self::_lookupStatusForObject(
835 self::LP_STATUS_FAILED_NUM,
845 ?array $a_user_ids =
null
847 return self::_lookupStatusForObject(
849 self::LP_STATUS_IN_PROGRESS_NUM,
862 $lp_invalid = array();
869 foreach ($memberships as $obj_id => $status) {
871 $lp_invalid[] = $obj_id;
875 return array_diff($a_obj_ids, $lp_invalid);
883 array &$a_coll_obj_ids
892 foreach ($existing as $obj_id => $obj_mode) {
894 $valid[$obj_id] = $obj_id;
896 if (in_array($obj_mode, $coll_modes)) {
897 $a_coll_obj_ids[] = $obj_id;
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) {
907 $mode = $olp->getCurrentMode();
912 $valid[$obj_id] = $obj_id;
914 if (in_array($mode, $coll_modes)) {
915 $a_coll_obj_ids[] = $obj_id;
921 return array_values(
$valid);
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"];
946 $res[$row[
"obj_id"]] = self::_lookupStatus(
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;
971 if (
$DIC->http()->wrapper()->query()->has(
'ref_id')) {
974 $DIC->refinery()->kindlyTo()->int()
978 $ilUser =
$DIC[
'ilUser'];
994 $coll_obj_ids = array();
995 $a_obj_ids = self::checkLPModesForObjects(
1002 $res = self::getLPStatusForObjects(
$user_id, $a_obj_ids);
1007 $lng->loadLanguageModule(
"trac");
1009 foreach (
$res as $obj_id => $status) {
1011 "image" => $icons->renderIconForStatus($status),
1017 self::$list_gui_cache =
$res;
1025 bool $a_image_only =
true
1027 if ($a_image_only) {
1029 if (isset(self::$list_gui_cache[$a_obj_id][
"image"])) {
1030 $image = self::$list_gui_cache[$a_obj_id][
"image"];
1035 return self::$list_gui_cache[$a_obj_id] ??
"";
1040 if (isset(self::$list_gui_cache[$a_obj_id])) {
static getCollectionModes()
const LP_MODE_DEACTIVATED
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
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.
_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.
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.
static _hasLearningProgressListGUI()
static _hasLearningProgressLearner()
static _enabledLearningProgress()
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)
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...