From a586401c121bc005d56bfe7fe84bbd9026550a73 Mon Sep 17 00:00:00 2001 From: Uwe Kohnle Date: Tue, 2 Apr 2024 22:40:46 +0000 Subject: [PATCH] fixes for grade table --- ...lass.ilLTIConsumerGradeSynchronization.php | 49 ++++++----- ...lLTIConsumerGradeSynchronizationFilter.php | 51 ++++++----- ...s.ilLTIConsumerGradeSynchronizationGUI.php | 87 ++++++++++++------- ...TIConsumerGradeSynchronizationTableGUI.php | 71 ++++++++------- ...l.lti_grade_synchronization_table_row.html | 10 +-- lang/ilias_de.lang | 23 +++-- lang/ilias_en.lang | 23 +++-- 7 files changed, 188 insertions(+), 126 deletions(-) diff --git a/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronization.php b/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronization.php index 585f90bd40b8..e4bae618cd16 100755 --- a/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronization.php +++ b/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronization.php @@ -1,7 +1,5 @@ * * @package Modules/LTIConsumer */ + class ilLTIConsumerGradeSynchronization { public int $id; @@ -36,18 +37,6 @@ class ilLTIConsumerGradeSynchronization */ public ?float $result = null; - /** - * Fill the properties with data from an array - * @param array assoc data - */ - // protected function fillData(array $data): void - // { - // $this->id = (int) $data['id']; - // $this->obj_id = (int) $data['obj_id']; - // $this->usr_id = (int) $data['usr_id']; - // $this->result = (float) $data['result']; - // } - public function getId(): int { @@ -69,22 +58,40 @@ public function getResult(): ?float return $this->result; } - /** - * @param $objId - * @return ilLTIConsumerResult[] - */ - public static function getGradesForObject(int $objId, ?int $usrID = null): array + public static function getGradesForObject(int $objId, ?int $usrID = null, ?string $activity_progress = null, ?string $grading_progress = null, ?ilDateTime $startDate = null, ?ilDateTime $endDate = null): array { global $DIC; /* @var \ILIAS\DI\Container $DIC */ $query = 'SELECT * FROM lti_consumer_grades' . ' WHERE obj_id = ' . $DIC->database()->quote($objId, 'integer'); + if ($usrID != null) { + $query .= ' AND usr_id = ' . $DIC->database()->quote($usrID, 'integer'); + } + + if ($activity_progress != null) { + $query .= ' AND activity_progress = ' . $DIC->database()->quote($activity_progress, 'text'); + } + + if ($grading_progress != null) { + $query .= ' AND grading_progress = ' . $DIC->database()->quote($grading_progress, 'text'); + } + + if ($startDate != null && $startDate->get(IL_CAL_DATETIME) != null) { + $query .= ' AND lti_timestamp >= ' . $DIC->database()->quote($startDate->get(IL_CAL_DATETIME), 'timestamp'); + } + + if ($endDate != null && $endDate->get(IL_CAL_DATETIME) != null) { + $query .= ' AND lti_timestamp <= ' . $DIC->database()->quote($endDate->get(IL_CAL_DATETIME), 'timestamp'); + } + + $query .= ' ORDER BY lti_timestamp DESC'; + $res = $DIC->database()->query($query); $results = []; - if ($row = $DIC->database()->fetchAssoc($res)) { + while ($row = $DIC->database()->fetchAssoc($res)) { $results[] = $row; } diff --git a/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronizationFilter.php b/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronizationFilter.php index 060efc068a3c..4bf975660deb 100644 --- a/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronizationFilter.php +++ b/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronizationFilter.php @@ -1,7 +1,5 @@ activityId; - } + protected ?ilDateTime $endDate = null; - public function setActivityId(string $activityId): void - { - $this->activityId = $activityId; - } public function getLimit(): int { @@ -96,42 +89,52 @@ public function setOrderDirection(string $orderDirection): void $this->orderDirection = $orderDirection; } - public function getActor(): ?\ilCmiXapiUser + public function getActor(): ?int { return $this->actor; } - public function setActor(\ilCmiXapiUser $actor): void + public function setActor(int $actor): void { $this->actor = $actor; } - public function getVerb(): ?string + public function getActivityProgress(): ?string + { + return $this->activity_progress; + } + + public function setActivityProgress(string $activityProgress): void + { + $this->activity_progress = $activityProgress; + } + + public function getGradingProgress(): ?string { - return $this->verb; + return $this->grading_progress; } - public function setVerb(string $verb): void + public function setGradingProgress(string $gradingProgress): void { - $this->verb = $verb; + $this->grading_progress = $gradingProgress; } - public function getStartDate(): ?\ilCmiXapiDateTime + public function getStartDate(): ?\ilDateTime { return $this->startDate; } - public function setStartDate(\ilCmiXapiDateTime $startDate): void + public function setStartDate(\ilDateTime $startDate): void { $this->startDate = $startDate; } - public function getEndDate(): ?\ilCmiXapiDateTime + public function getEndDate(): ?\ilDateTime { return $this->endDate; } - public function setEndDate(\ilCmiXapiDateTime $endDate): void + public function setEndDate(\ilDateTime $endDate): void { $this->endDate = $endDate; } diff --git a/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronizationGUI.php b/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronizationGUI.php index bdd27d45fc0a..fcd385b1e55e 100644 --- a/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronizationGUI.php +++ b/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronizationGUI.php @@ -1,7 +1,5 @@ setActivityId($this->object->getProvider()->getContentItemUrl()); - $this->initLimitingAndOrdering($statementsFilter, $table); $this->initActorFilter($statementsFilter, $table); - $this->initVerbFilter($statementsFilter, $table); + $this->initActivityProgressFilter($statementsFilter, $table); + $this->initGradingProgressFilter($statementsFilter, $table); $this->initPeriodFilter($statementsFilter, $table); $this->initTableData($table, $statementsFilter); } catch (Exception $e) { @@ -113,7 +106,7 @@ protected function showCmd(): void protected function initLimitingAndOrdering(ilLTIConsumerGradeSynchronizationFilter $filter, ilLTIConsumerGradeSynchronizationTableGUI $table): void { - $table->determineOffsetAndOrder(); + $table->determineOffsetAndOrder(true); $filter->setLimit($table->getLimit()); $filter->setOffset($table->getOffset()); @@ -137,26 +130,33 @@ protected function initActorFilter(ilLTIConsumerGradeSynchronizationFilter $filt $usrId = ilObjUser::getUserIdByLogin($actor); if ($usrId) { - $filter->setActor(new ilCmiXapiUser($this->object->getId(), $usrId, $this->object->getProvider()->getPrivacyIdent())); - } else { - throw new ilCmiXapiInvalidStatementsFilterException( - "given actor ({$actor}) is not a valid actor for object ({$this->object->getId()})" - ); + $filter->setActor($usrId); } } } else { - $filter->setActor(new ilCmiXapiUser($this->object->getId(), $DIC->user()->getId(), $this->object->getProvider()->getPrivacyIdent())); + $filter->setActor($DIC->user()->getId()); + } + } + + protected function initActivityProgressFilter(ilLTIConsumerGradeSynchronizationFilter $filter, ilLTIConsumerGradeSynchronizationTableGUI $table): void + { + $activityProgress = urldecode($table->getFilterItemByPostVar('activity_progress')->getValue()); + + $allowed = ['Initialized', 'Started', 'InProgress', 'Submitted', 'Completed']; + + if (in_array($activityProgress, $allowed)) { + $filter->setActivityProgress($activityProgress); } } - protected function initVerbFilter(ilLTIConsumerGradeSynchronizationFilter $filter, ilLTIConsumerGradeSynchronizationTableGUI $table): void + protected function initGradingProgressFilter(ilLTIConsumerGradeSynchronizationFilter $filter, ilLTIConsumerGradeSynchronizationTableGUI $table): void { - $verb = urldecode($table->getFilterItemByPostVar('verb')->getValue()); + $gradingProgress = urldecode($table->getFilterItemByPostVar('grading_progress')->getValue()); - $verbsallowed = ['completed', 'passed']; + $allowed = ['FullyGraded', 'Pending', 'PendingManual', 'Failed', 'NotReady']; - if (in_array($verb, $verbsallowed)) { - $filter->setVerb($verb); + if (in_array($gradingProgress, $allowed)) { + $filter->setGradingProgress($gradingProgress); } } @@ -164,12 +164,12 @@ protected function initPeriodFilter(ilLTIConsumerGradeSynchronizationFilter $fil { $period = $table->getFilterItemByPostVar('period'); - if ($period->getStartXapiDateTime()) { - $filter->setStartDate($period->getStartXapiDateTime()); + if ($period->getStart()) { + $filter->setStartDate($period->getStart()); } - if ($period->getEndXapiDateTime()) { - $filter->setEndDate($period->getEndXapiDateTime()); + if ($period->getEnd()) { + $filter->setEndDate($period->getEnd()); } } @@ -197,8 +197,37 @@ public function asyncUserAutocompleteCmd(): void protected function initTableData(ilLTIConsumerGradeSynchronizationTableGUI $table, ilLTIConsumerGradeSynchronizationFilter $filter): void { - $table->setData(ilLTIConsumerGradeSynchronization::getGradesForObject($this->object->getId())); - // $table->setMaxCount($statementsReport->getMaxCount()); + $cUser = null; + if (!$this->access->hasOutcomesAccess()) { + $cUser = $this->dic->user()->getId(); + } else { + $cUser = $filter->getActor(); + } + $data = ilLTIConsumerGradeSynchronization::getGradesForObject( + $this->object->getId(), + $cUser, + $filter->getActivityProgress(), + $filter->getGradingProgress(), + $filter->getStartDate(), + $filter->getEndDate() + ); + + for ((int) $i = 0; $i < count($data); $i++) { + $usr = new ilObjUser((int) $data[$i]['usr_id']); + $data[$i]['actor'] = $usr->getFullname(); + } + $sortNum = false; + if ($table->getOrderField() == 'score_given') { + $sortNum = true; + } + + $data = ilArrayUtil::sortArray( + $data, + $table->getOrderField(), + $table->getOrderDirection(), + $sortNum + ); + $table->setData($data); } protected function buildTableGUI(): ilLTIConsumerGradeSynchronizationTableGUI diff --git a/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronizationTableGUI.php b/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronizationTableGUI.php index b59e7c9af23c..9137e9b6e880 100644 --- a/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronizationTableGUI.php +++ b/Modules/LTIConsumer/classes/class.ilLTIConsumerGradeSynchronizationTableGUI.php @@ -1,7 +1,5 @@ dic = $DIC; - $DIC->language()->loadLanguageModule('cmix'); $this->language = $DIC->language(); $this->isMultiActorReport = $isMultiActorReport; @@ -63,28 +57,24 @@ public function __construct(?object $a_parent_obj, string $a_parent_cmd, bool $i $this->initColumns(); $this->initFilter(); - $this->setExternalSegmentation(true); + $this->setExternalSegmentation(false); $this->setExternalSorting(true); - $this->setDefaultOrderField('date'); + $this->setDefaultOrderField('lti_timestamp'); $this->setDefaultOrderDirection('desc'); } protected function initColumns(): void { - $this->addColumn($this->language->txt('tbl_grade_date'), 'date'); + $this->addColumn($this->language->txt('tbl_grade_date'), 'lti_timestamp'); if ($this->isMultiActorReport) { $this->addColumn($this->language->txt('tbl_grade_actor'), 'actor'); } - - $this->addColumn($this->language->txt('tbl_grade_object'), 'object'); //label otherwise id - - $this->addColumn($this->language->txt('tbl_grade_activityProgress'), 'verb'); //activityProgress - // gradingProgress necessary? - $this->addColumn($this->language->txt('tbl_grade_score'), 'score'); - - $this->addColumn('', '', '1%'); + $this->addColumn($this->language->txt('tbl_grade_score'), 'score_given'); + $this->addColumn($this->language->txt('tbl_grade_activity_progress'), ''); + $this->addColumn($this->language->txt('tbl_grade_grading_progress'), ''); + $this->addColumn($this->language->txt('tbl_grade_stored'), ''); } public function initFilter(): void @@ -100,18 +90,36 @@ public function initFilter(): void } $options = array( - '' => $this->language->txt('grade_all_verbs'), - 'completed' => $this->language->txt('grade_activityProgress_completed'), - 'passed' => $this->language->txt('grade_activityProgress_passed'), + '' => $this->language->txt('grade_activity_progress_all'), + 'Initialized' => $this->language->txt('grade_activity_progress_initialized'), + 'Started' => $this->language->txt('grade_activity_progress_started'), + 'InProgress' => $this->language->txt('grade_activity_progress_inprogress'), + 'Submitted' => $this->language->txt('grade_activity_progress_submitted'), + 'Completed' => $this->language->txt('grade_activity_progress_completed') + ); + + $si = new ilSelectInputGUI($this->language->txt('tbl_grade_activity_progress'), "activity_progress"); + $si->setOptions($options); + $this->addFilterItem($si); + $si->readFromSession(); + $this->filter["activity_progress"] = $si->getValue(); + + $options = array( + '' => $this->language->txt('grade_grading_progress_all'), + 'NotReady' => $this->language->txt('grade_grading_progress_notready'), + 'Failed' => $this->language->txt('grade_grading_progress_failed'), + 'Pending' => $this->language->txt('grade_grading_progress_pending'), + 'PendingManual' => $this->language->txt('grade_grading_progress_pendingmanual'), + 'FullyGraded' => $this->language->txt('grade_grading_progress_fullygraded') ); - $si = new ilSelectInputGUI($this->language->txt('tbl_grade_activityProgress_select'), "verb"); + $si = new ilSelectInputGUI($this->language->txt('tbl_grade_grading_progress'), "grading_progress"); $si->setOptions($options); $this->addFilterItem($si); $si->readFromSession(); - $this->filter["verb"] = $si->getValue(); + $this->filter["grading_progress"] = $si->getValue(); - $dp = new ilCmiXapiDateDurationInputGUI($this->language->txt('tbl_grade_period'), 'period'); + $dp = new ilDateDurationInputGUI($this->language->txt('tbl_grade_period'), 'period'); $dp->setShowTime(true); $this->addFilterItem($dp); $dp->readFromSession(); @@ -120,15 +128,14 @@ public function initFilter(): void protected function fillRow(array $a_set): void { - $this->tpl->setVariable('STMT_DATE', $a_set['lti_timestamp']); - $usr = new ilObjUser((int) $a_set['usr_id']); - $this->tpl->setVariable('STMT_ACTOR', $usr->getFullname()); - - $this->tpl->setVariable('STMT_OBJECT', $this->language->txt('grade_grading_' . $a_set['grading_progress'])); - - $this->tpl->setVariable('STMT_VERB', $this->language->txt('grade_activity_' . $a_set['activity_progress'])); - + $this->tpl->setVariable('STMT_DATE', ilDatePresentation::formatDate(new ilDateTime($a_set['lti_timestamp'], IL_CAL_DATETIME))); + if ($this->isMultiActorReport) { + $this->tpl->setVariable('STMT_ACTOR', $a_set['actor']); + } $this->tpl->setVariable('STMT_SCORE', $a_set['score_given'] . ' / ' . $a_set['score_maximum']); + $this->tpl->setVariable('STMT_ACTIVITY_PROGRESS', $this->language->txt('grade_activity_progress_' . strtolower($a_set['activity_progress']))); + $this->tpl->setVariable('STMT_GRADING_PROGRESS', $this->language->txt('grade_grading_progress_' . strtolower($a_set['grading_progress']))); + $this->tpl->setVariable('STMT_STORED', ilDatePresentation::formatDate(new ilDateTime($a_set['stored'], IL_CAL_DATETIME))); } } diff --git a/Modules/LTIConsumer/templates/default/tpl.lti_grade_synchronization_table_row.html b/Modules/LTIConsumer/templates/default/tpl.lti_grade_synchronization_table_row.html index 25189a892dbc..ff98c8fc6c55 100644 --- a/Modules/LTIConsumer/templates/default/tpl.lti_grade_synchronization_table_row.html +++ b/Modules/LTIConsumer/templates/default/tpl.lti_grade_synchronization_table_row.html @@ -3,10 +3,8 @@ {STMT_ACTOR} - {STMT_VERB} - -
{STMT_OBJECT}
-
{STMT_OBJECT_INFO}
- - {STMT_SCORE} + {STMT_SCORE} + {STMT_ACTIVITY_PROGRESS} + {STMT_GRADING_PROGRESS} + {STMT_STORED} \ No newline at end of file diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index 866ea76133bd..aedfabebd27b 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -10585,9 +10585,18 @@ lti#:#field_provider_xml_info#:#Unterstützt werden XML-Dateien für Tool Consum lti#:#form_import_provider#:#Globalen Provider bzw. globales Tool importieren lti#:#gbl_roles_to_users#:#LTI-Nutzern zugeordnete globale Rolle lti#:#global_provider_subtab#:#Globale Provider bzw. Tools für alle Anwender -lti#:#grade_activityProgress_completed#:#vollständig bearbeitet -lti#:#grade_activityProgress_passed#:#bestanden -lti#:#grade_all_verbs#:#alle Statusangaben +lti#:#grade_activity_progress_all#:#alle Angaben zum Aktivitätsfortschritt +lti#:#grade_activity_progress_completed#:#vollständig bearbeitet (Completed) +lti#:#grade_activity_progress_initialized#:#begonnen (Initialized) +lti#:#grade_activity_progress_inprogress#:#in Bearbeitung (InProgress) +lti#:#grade_activity_progress_started#:#gestartet (Started) +lti#:#grade_activity_progress_submitted#:#eingereicht (Submitted) +lti#:#grade_grading_progress_all#:#alle Angaben zum Benotungsfortschritt +lti#:#grade_grading_progress_failed#:#Die Benotung konnte nicht abgeschlossen werden (Failed). +lti#:#grade_grading_progress_fullygraded#:#Der Benotungsprozess ist abgeschlossen. +lti#:#grade_grading_progress_notready#:#Es fand keine Benotung statt (NotReady). +lti#:#grade_grading_progress_pending#:#Die Endnote steht noch aus. +lti#:#grade_grading_progress_pendingmanual#:#Die Endnote steht noch aus; erfordert menschliche Intervention. lti#:#highscore_achieved_ts#:#Datum lti#:#highscore_achieved_ts_description#:#Eine Spalte mit dem Datum wird in die Platzierungen aufgenommen. lti#:#highscore_all_tables#:#Eigener Rang und Bestenliste @@ -10798,13 +10807,13 @@ lti#:#tab_info#:#Info lti#:#tab_scoring#:#Platzierungen lti#:#tab_settings#:#Einstellungen lti#:#tab_statements#:#Lernerfahrungen -lti#:#tbl_grade_activityProgress#:#Auswahl Status -lti#:#tbl_grade_activityProgress_select#:#Status -lti#:#tbl_grade_actor#:#Benutzer +lti#:#tbl_grade_activity_progress#:#Aktivitätsfortschritt +lti#:#tbl_grade_actor#:#Name lti#:#tbl_grade_date#:#Datum -lti#:#tbl_grade_object#:#Objekt +lti#:#tbl_grade_grading_progress#:#Benotungsfortschritt lti#:#tbl_grade_period#:#Zeitraum lti#:#tbl_grade_score#:#Punkte +lti#:#tbl_grade_stored#:#übermittelt an ILIAS lti#:#tbl_lti_prov_all_categories#:#Alle Kategorien lti#:#tbl_lti_prov_availability#:#Verfügbarkeit lti#:#tbl_lti_prov_category#:#Kategorie diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index e8af6743d3f8..6d0fc853ca41 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -10584,10 +10584,19 @@ lti#:#field_provider_xml#:#XML-File lti#:#field_provider_xml_info#:#Supported are XML-Files for Tool Consumer and for Common Cartridge according to https://www.imsglobal.org/specs/lti/xml. lti#:#form_import_provider#:#Import Global Provider lti#:#gbl_roles_to_users#:#Global Role assigned to LTI Users -lti#:#global_provider_subtab#:#Global Providers for all Users -lti#:#grade_activityProgress_completed#:#completed -lti#:#grade_activityProgress_passed#:#passed -lti#:#grade_all_verbs#:#all status information +lti#:#global_provider_subtab#:#Global Providers/Tools for all Users +lti#:#grade_activity_progress_all#:#All Information on Activity Progress +lti#:#grade_activity_progress_completed#:#Completed +lti#:#grade_activity_progress_initialized#:#Initialized +lti#:#grade_activity_progress_inprogress#:#In Progress +lti#:#grade_activity_progress_started#:#Started +lti#:#grade_activity_progress_submitted#:#Submitted +lti#:#grade_grading_progress_all#:#All Information on Grading Progress +lti#:#grade_grading_progress_failed#:#The Grading could not complete (Failed) +lti#:#grade_grading_progress_fullygraded#:#The Grading Process is completed +lti#:#grade_grading_progress_notready#:#No Grading Process is occurring (NotReady) +lti#:#grade_grading_progress_pending#:#Final Grade is pending +lti#:#grade_grading_progress_pendingmanual#:#Final Grade is pending; requires Human Intervention lti#:#highscore_achieved_ts#:#Date lti#:#highscore_achieved_ts_description#:#A column containing the date will be included in the ranking. lti#:#highscore_all_tables#:#Participant's Own Rank and Top Ranking @@ -10798,13 +10807,13 @@ lti#:#tab_info#:#Info lti#:#tab_scoring#:#Ranking lti#:#tab_settings#:#Settings lti#:#tab_statements#:#Learning Experiences -lti#:#tbl_grade_activityProgress#:#Status Selection -lti#:#tbl_grade_activityProgress_select#:#Status +lti#:#tbl_grade_activity_progress#:#Activity Progress lti#:#tbl_grade_actor#:#User lti#:#tbl_grade_date#:#Date -lti#:#tbl_grade_object#:#Object +lti#:#tbl_grade_grading_progress#:#Grading Progress lti#:#tbl_grade_period#:#Period lti#:#tbl_grade_score#:#Score +lti#:#tbl_grade_stored#:#Transmitted to ILIAS lti#:#tbl_lti_prov_all_categories#:#All Categories lti#:#tbl_lti_prov_availability#:#Availability lti#:#tbl_lti_prov_category#:#Category