From dd94d78df7505d1d195fa7942b7f574afe3e08ef Mon Sep 17 00:00:00 2001 From: Karol Stelmaczonek Date: Tue, 5 Dec 2023 09:11:59 +0100 Subject: [PATCH 1/7] feature: add new event ResultTestVariablesAfterTransmissionEvent --- helpers/class.TestSession.php | 41 +++++++++++++- ...ultTestVariablesAfterTransmissionEvent.php | 56 +++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 models/classes/event/ResultTestVariablesAfterTransmissionEvent.php diff --git a/helpers/class.TestSession.php b/helpers/class.TestSession.php index 5241e338f..41fb91b70 100644 --- a/helpers/class.TestSession.php +++ b/helpers/class.TestSession.php @@ -20,12 +20,15 @@ */ use oat\oatbox\event\EventManager; +use oat\oatbox\service\exception\InvalidServiceManagerException; use oat\oatbox\service\ServiceManager; use oat\taoQtiTest\helpers\TestSessionMemento; use oat\taoQtiTest\models\classes\event\ResultTestVariablesTransmissionEvent; use oat\taoQtiTest\models\event\QtiTestChangeEvent; use oat\taoQtiTest\models\event\QtiTestStateChangeEvent; use oat\taoQtiTest\models\event\ResultItemVariablesTransmissionEvent; +use oat\taoQtiTest\models\event\ResultTestVariablesAfterTransmissionEvent; +use oat\taoResultServer\models\classes\implementation\ResultServerService; use oat\taoResultServer\models\classes\ResultStorageWrapper; use oat\taoTests\models\event\TestExecutionPausedEvent; use oat\taoTests\models\event\TestExecutionResumedEvent; @@ -57,6 +60,8 @@ use qtism\runtime\tests\Route; use Symfony\Component\Lock\LockInterface; use Zend\ServiceManager\ServiceLocatorAwareInterface; +use taoResultServer_models_classes_ReadableResultStorage as ReadableResultStorage; + /** * A TAO Specific extension of QtiSm's AssessmentTestSession class. @@ -814,11 +819,29 @@ private function triggerResultTestVariablesTransmissionEvent( array $variables, string $testUri = '' ): void { - $this->getEventManager()->trigger(new ResultTestVariablesTransmissionEvent( + $event = new ResultTestVariablesTransmissionEvent( $this->getSessionId(), $variables, $this->getSessionId(), $testUri + ); + + $this->getEventManager()->attach($event, [$this, 'attachToTransmissionEvent']); + $this->getEventManager()->trigger($event); + } + + public function attachToTransmissionEvent(ResultTestVariablesTransmissionEvent $event): void + { + $scoreTotal = array_filter($event->getVariables(), function ($item) { + return $item->getIdentifier() === 'SCORE_TOTAL'; + })[0]; + if ($scoreTotal === null) { + return; + } + $outcomeVariables = $this->getResultsStorage()->getDeliveryVariables($event->getDeliveryExecutionId()); + $this->getEventManager()->trigger(new ResultTestVariablesAfterTransmissionEvent( + $event->getDeliveryExecutionId(), + $outcomeVariables )); } @@ -882,4 +905,20 @@ protected function getSessionMemento() { return new TestSessionMemento($this); } + + /** + * @throws common_exception_Error + * @throws InvalidServiceManagerException + */ + private function getResultsStorage(): ReadableResultStorage + { + $resultServerService = $this->getServiceLocator()->get(ResultServerService::SERVICE_ID); + $storage = $resultServerService->getResultStorage(); + + if (!$storage instanceof ReadableResultStorage) { + throw new common_exception_Error('Configured result storage is not writable.'); + } + + return $storage; + } } diff --git a/models/classes/event/ResultTestVariablesAfterTransmissionEvent.php b/models/classes/event/ResultTestVariablesAfterTransmissionEvent.php new file mode 100644 index 000000000..c09b0c072 --- /dev/null +++ b/models/classes/event/ResultTestVariablesAfterTransmissionEvent.php @@ -0,0 +1,56 @@ +deliveryExecutionId = $deliveryExecutionId; + $this->variables = $variables; + } + + public function getName(): string + { + return self::class; + } + + public function getDeliveryExecutionId(): string + { + return $this->deliveryExecutionId; + } + + public function getVariables(): array + { + return $this->variables; + } +} From afc266d765a2ca8ed055a1fe2ccd898dc4830e4b Mon Sep 17 00:00:00 2001 From: Karol Stelmaczonek Date: Tue, 5 Dec 2023 15:19:04 +0100 Subject: [PATCH 2/7] feature: rewrite LtiAgsListener --- helpers/class.TestSession.php | 20 ++++++++++++++++++- ...ultTestVariablesAfterTransmissionEvent.php | 10 +++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/helpers/class.TestSession.php b/helpers/class.TestSession.php index 41fb91b70..23e4a8b67 100644 --- a/helpers/class.TestSession.php +++ b/helpers/class.TestSession.php @@ -47,6 +47,7 @@ use qtism\data\processing\OutcomeProcessing; use qtism\data\rules\OutcomeRuleCollection; use qtism\data\rules\SetOutcomeValue; +use qtism\data\state\OutcomeDeclaration; use qtism\runtime\common\OutcomeVariable; use qtism\runtime\common\ProcessingException; use qtism\runtime\processing\OutcomeProcessingEngine; @@ -841,10 +842,27 @@ public function attachToTransmissionEvent(ResultTestVariablesTransmissionEvent $ $outcomeVariables = $this->getResultsStorage()->getDeliveryVariables($event->getDeliveryExecutionId()); $this->getEventManager()->trigger(new ResultTestVariablesAfterTransmissionEvent( $event->getDeliveryExecutionId(), - $outcomeVariables + $outcomeVariables, + $this->isManualScored() )); } + private function isManualScored(): bool + { + /** @var AssessmentItemRef $itemRef */ + foreach ($this->getRoute()->getAssessmentItemRefs() as $itemRef) { + foreach ($itemRef->getComponents() as $component) { + if ($component instanceof OutcomeDeclaration) { + if ($component->isExternallyScored()) { + return true; + } + } + } + } + + return false; + } + /** * @param TestSessionMemento $sessionMemento */ diff --git a/models/classes/event/ResultTestVariablesAfterTransmissionEvent.php b/models/classes/event/ResultTestVariablesAfterTransmissionEvent.php index c09b0c072..5b8f25442 100644 --- a/models/classes/event/ResultTestVariablesAfterTransmissionEvent.php +++ b/models/classes/event/ResultTestVariablesAfterTransmissionEvent.php @@ -30,13 +30,16 @@ class ResultTestVariablesAfterTransmissionEvent implements Event private string $deliveryExecutionId; private array $variables; + private bool $isManualScored; public function __construct( string $deliveryExecutionId, - array $variables + array $variables, + bool $isManualScored ) { $this->deliveryExecutionId = $deliveryExecutionId; $this->variables = $variables; + $this->isManualScored = $isManualScored; } public function getName(): string @@ -53,4 +56,9 @@ public function getVariables(): array { return $this->variables; } + + public function getIsManualScored(): bool + { + return $this->isManualScored; + } } From f70f5f8d0848c220b2f0e9fc659ebec415e888b5 Mon Sep 17 00:00:00 2001 From: Karol Stelmaczonek Date: Tue, 5 Dec 2023 15:54:09 +0100 Subject: [PATCH 3/7] fix: codestyle --- helpers/class.TestSession.php | 1 - 1 file changed, 1 deletion(-) diff --git a/helpers/class.TestSession.php b/helpers/class.TestSession.php index 23e4a8b67..af9b99a71 100644 --- a/helpers/class.TestSession.php +++ b/helpers/class.TestSession.php @@ -63,7 +63,6 @@ use Zend\ServiceManager\ServiceLocatorAwareInterface; use taoResultServer_models_classes_ReadableResultStorage as ReadableResultStorage; - /** * A TAO Specific extension of QtiSm's AssessmentTestSession class. * From 18a4ac29d084e56d743e3a295164c5897b477c75 Mon Sep 17 00:00:00 2001 From: Karol Stelmaczonek Date: Tue, 5 Dec 2023 15:55:29 +0100 Subject: [PATCH 4/7] fix: codestyle --- .../classes/event/ResultTestVariablesAfterTransmissionEvent.php | 1 - 1 file changed, 1 deletion(-) diff --git a/models/classes/event/ResultTestVariablesAfterTransmissionEvent.php b/models/classes/event/ResultTestVariablesAfterTransmissionEvent.php index 5b8f25442..7ae705af7 100644 --- a/models/classes/event/ResultTestVariablesAfterTransmissionEvent.php +++ b/models/classes/event/ResultTestVariablesAfterTransmissionEvent.php @@ -20,7 +20,6 @@ declare(strict_types=1); - namespace oat\taoQtiTest\models\event; use oat\oatbox\event\Event; From 3b923a9f9b41d9035a2c5ce8a51d498976cba134 Mon Sep 17 00:00:00 2001 From: Karol Stelmaczonek Date: Wed, 6 Dec 2023 17:01:57 +0100 Subject: [PATCH 5/7] fix: code review --- helpers/class.TestSession.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/helpers/class.TestSession.php b/helpers/class.TestSession.php index af9b99a71..97099ea19 100644 --- a/helpers/class.TestSession.php +++ b/helpers/class.TestSession.php @@ -832,10 +832,14 @@ private function triggerResultTestVariablesTransmissionEvent( public function attachToTransmissionEvent(ResultTestVariablesTransmissionEvent $event): void { - $scoreTotal = array_filter($event->getVariables(), function ($item) { - return $item->getIdentifier() === 'SCORE_TOTAL'; - })[0]; - if ($scoreTotal === null) { + $scoreTotal = array_filter( + $event->getVariables(), + function ($item) { + return $item->getIdentifier() === 'SCORE_TOTAL'; + } + ); + + if (empty($scoreTotal)) { return; } $outcomeVariables = $this->getResultsStorage()->getDeliveryVariables($event->getDeliveryExecutionId()); @@ -851,10 +855,11 @@ private function isManualScored(): bool /** @var AssessmentItemRef $itemRef */ foreach ($this->getRoute()->getAssessmentItemRefs() as $itemRef) { foreach ($itemRef->getComponents() as $component) { - if ($component instanceof OutcomeDeclaration) { - if ($component->isExternallyScored()) { - return true; - } + if ( + $component instanceof OutcomeDeclaration + && $component->isExternallyScored() + ) { + return true; } } } From 39257533d716ab0ef04519fa8082a35de23d5e4a Mon Sep 17 00:00:00 2001 From: Karol Stelmaczonek Date: Thu, 7 Dec 2023 18:51:23 +0100 Subject: [PATCH 6/7] feature: change to TestVariablesRecorded, and use it in ResultTransmissionEventHandler --- helpers/class.TestSession.php | 46 +------------ .../ResultTestVariablesTransmissionEvent.php | 11 ++- ...ionEvent.php => TestVariablesRecorded.php} | 3 +- .../ResultTransmissionEventHandler.php | 69 +++++++++++++++++++ 4 files changed, 82 insertions(+), 47 deletions(-) rename models/classes/event/{ResultTestVariablesAfterTransmissionEvent.php => TestVariablesRecorded.php} (96%) diff --git a/helpers/class.TestSession.php b/helpers/class.TestSession.php index 97099ea19..23bf7ed26 100644 --- a/helpers/class.TestSession.php +++ b/helpers/class.TestSession.php @@ -20,15 +20,12 @@ */ use oat\oatbox\event\EventManager; -use oat\oatbox\service\exception\InvalidServiceManagerException; use oat\oatbox\service\ServiceManager; use oat\taoQtiTest\helpers\TestSessionMemento; use oat\taoQtiTest\models\classes\event\ResultTestVariablesTransmissionEvent; use oat\taoQtiTest\models\event\QtiTestChangeEvent; use oat\taoQtiTest\models\event\QtiTestStateChangeEvent; use oat\taoQtiTest\models\event\ResultItemVariablesTransmissionEvent; -use oat\taoQtiTest\models\event\ResultTestVariablesAfterTransmissionEvent; -use oat\taoResultServer\models\classes\implementation\ResultServerService; use oat\taoResultServer\models\classes\ResultStorageWrapper; use oat\taoTests\models\event\TestExecutionPausedEvent; use oat\taoTests\models\event\TestExecutionResumedEvent; @@ -61,7 +58,6 @@ use qtism\runtime\tests\Route; use Symfony\Component\Lock\LockInterface; use Zend\ServiceManager\ServiceLocatorAwareInterface; -use taoResultServer_models_classes_ReadableResultStorage as ReadableResultStorage; /** * A TAO Specific extension of QtiSm's AssessmentTestSession class. @@ -819,33 +815,11 @@ private function triggerResultTestVariablesTransmissionEvent( array $variables, string $testUri = '' ): void { - $event = new ResultTestVariablesTransmissionEvent( + $this->getEventManager()->trigger(new ResultTestVariablesTransmissionEvent( $this->getSessionId(), $variables, $this->getSessionId(), - $testUri - ); - - $this->getEventManager()->attach($event, [$this, 'attachToTransmissionEvent']); - $this->getEventManager()->trigger($event); - } - - public function attachToTransmissionEvent(ResultTestVariablesTransmissionEvent $event): void - { - $scoreTotal = array_filter( - $event->getVariables(), - function ($item) { - return $item->getIdentifier() === 'SCORE_TOTAL'; - } - ); - - if (empty($scoreTotal)) { - return; - } - $outcomeVariables = $this->getResultsStorage()->getDeliveryVariables($event->getDeliveryExecutionId()); - $this->getEventManager()->trigger(new ResultTestVariablesAfterTransmissionEvent( - $event->getDeliveryExecutionId(), - $outcomeVariables, + $testUri, $this->isManualScored() )); } @@ -927,20 +901,4 @@ protected function getSessionMemento() { return new TestSessionMemento($this); } - - /** - * @throws common_exception_Error - * @throws InvalidServiceManagerException - */ - private function getResultsStorage(): ReadableResultStorage - { - $resultServerService = $this->getServiceLocator()->get(ResultServerService::SERVICE_ID); - $storage = $resultServerService->getResultStorage(); - - if (!$storage instanceof ReadableResultStorage) { - throw new common_exception_Error('Configured result storage is not writable.'); - } - - return $storage; - } } diff --git a/models/classes/event/ResultTestVariablesTransmissionEvent.php b/models/classes/event/ResultTestVariablesTransmissionEvent.php index 315f98d34..51ba39b1a 100644 --- a/models/classes/event/ResultTestVariablesTransmissionEvent.php +++ b/models/classes/event/ResultTestVariablesTransmissionEvent.php @@ -34,17 +34,21 @@ class ResultTestVariablesTransmissionEvent implements Event private $transmissionId; /** @var string */ private $testUri; + /** @var bool */ + private bool $isManualScored; public function __construct( string $deliveryExecutionId, array $variables, string $transmissionId, - string $testUri = '' + string $testUri = '', + bool $isManualScored = null, ) { $this->deliveryExecutionId = $deliveryExecutionId; $this->variables = $variables; $this->transmissionId = $transmissionId; $this->testUri = $testUri; + $this->isManualScored = $isManualScored; } public function getName(): string @@ -71,4 +75,9 @@ public function getTestUri(): string { return $this->testUri; } + + public function isManualScored(): bool + { + return $this->isManualScored; + } } diff --git a/models/classes/event/ResultTestVariablesAfterTransmissionEvent.php b/models/classes/event/TestVariablesRecorded.php similarity index 96% rename from models/classes/event/ResultTestVariablesAfterTransmissionEvent.php rename to models/classes/event/TestVariablesRecorded.php index 7ae705af7..6f8c39e3c 100644 --- a/models/classes/event/ResultTestVariablesAfterTransmissionEvent.php +++ b/models/classes/event/TestVariablesRecorded.php @@ -24,10 +24,9 @@ use oat\oatbox\event\Event; -class ResultTestVariablesAfterTransmissionEvent implements Event +class TestVariablesRecorded implements Event { private string $deliveryExecutionId; - private array $variables; private bool $isManualScored; diff --git a/models/classes/eventHandler/ResultTransmissionEventHandler/ResultTransmissionEventHandler.php b/models/classes/eventHandler/ResultTransmissionEventHandler/ResultTransmissionEventHandler.php index 64c5a2a20..6a1beec6d 100644 --- a/models/classes/eventHandler/ResultTransmissionEventHandler/ResultTransmissionEventHandler.php +++ b/models/classes/eventHandler/ResultTransmissionEventHandler/ResultTransmissionEventHandler.php @@ -22,11 +22,17 @@ namespace oat\taoQtiTest\models\classes\eventHandler\ResultTransmissionEventHandler; +use oat\oatbox\event\EventManager; +use oat\oatbox\service\ServiceManager; use oat\tao\model\service\InjectionAwareService; use oat\taoDelivery\model\execution\DeliveryServerService; use oat\taoQtiTest\models\classes\event\ResultTestVariablesTransmissionEvent; use oat\taoQtiTest\models\event\ResultItemVariablesTransmissionEvent; +use oat\taoQtiTest\models\event\TestVariablesRecorded; use taoQtiCommon_helpers_ResultTransmitter; +use oat\oatbox\service\exception\InvalidServiceManagerException; +use oat\taoResultServer\models\classes\implementation\ResultServerService; +use taoResultServer_models_classes_ReadableResultStorage as ReadableResultStorage; class ResultTransmissionEventHandler extends InjectionAwareService implements Api\ResultTransmissionEventHandlerInterface @@ -45,6 +51,8 @@ public function transmitResultItemVariable(ResultItemVariablesTransmissionEvent } /** + * @param ResultTestVariablesTransmissionEvent $event + * @throws InvalidServiceManagerException * @throws \taoQtiCommon_helpers_ResultTransmissionException */ public function transmitResultTestVariable(ResultTestVariablesTransmissionEvent $event): void @@ -54,6 +62,12 @@ public function transmitResultTestVariable(ResultTestVariablesTransmissionEvent $event->getTransmissionId(), $event->getTestUri() ); + + if (empty($this->containsScoreTotal($event))) { + return; + } + + $this->triggerTestVariablesRecorded($event); } private function buildTransmitter($deliveryExecutionId): taoQtiCommon_helpers_ResultTransmitter @@ -64,4 +78,59 @@ private function buildTransmitter($deliveryExecutionId): taoQtiCommon_helpers_Re return new taoQtiCommon_helpers_ResultTransmitter($resultStore); } + + public function getEventManager() + { + return $this->getServiceLocator()->get(EventManager::SERVICE_ID); + } + + public function getServiceLocator() + { + return ServiceManager::getServiceManager(); + } + + /** + * @throws common_exception_Error + * @throws InvalidServiceManagerException + */ + private function getResultsStorage(): ReadableResultStorage + { + $resultServerService = $this->getServiceLocator()->get(ResultServerService::SERVICE_ID); + $storage = $resultServerService->getResultStorage(); + + if (!$storage instanceof ReadableResultStorage) { + throw new common_exception_Error('Configured result storage is not writable.'); + } + + return $storage; + } + + /** + * @param ResultTestVariablesTransmissionEvent $event + * @return array + */ + private function containsScoreTotal(ResultTestVariablesTransmissionEvent $event): array + { + return array_filter( + $event->getVariables(), + function ($item) { + return $item->getIdentifier() === 'SCORE_TOTAL'; + } + ); + } + + /** + * @param ResultTestVariablesTransmissionEvent $event + * @return void + * @throws InvalidServiceManagerException + */ + private function triggerTestVariablesRecorded(ResultTestVariablesTransmissionEvent $event): void + { + $outcomeVariables = $this->getResultsStorage()->getDeliveryVariables($event->getDeliveryExecutionId()); + $this->getEventManager()->trigger(new TestVariablesRecorded( + $event->getDeliveryExecutionId(), + $outcomeVariables, + $event->isManualScored() + )); + } } From 8318b4e726371ca4d6a24f98793c1abd48e87755 Mon Sep 17 00:00:00 2001 From: Karol Stelmaczonek Date: Fri, 8 Dec 2023 10:58:17 +0100 Subject: [PATCH 7/7] fix: code review fixes --- .../ResultTransmissionEventHandler.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/models/classes/eventHandler/ResultTransmissionEventHandler/ResultTransmissionEventHandler.php b/models/classes/eventHandler/ResultTransmissionEventHandler/ResultTransmissionEventHandler.php index 6a1beec6d..4d86b28fa 100644 --- a/models/classes/eventHandler/ResultTransmissionEventHandler/ResultTransmissionEventHandler.php +++ b/models/classes/eventHandler/ResultTransmissionEventHandler/ResultTransmissionEventHandler.php @@ -22,8 +22,10 @@ namespace oat\taoQtiTest\models\classes\eventHandler\ResultTransmissionEventHandler; +use common_exception_Error; use oat\oatbox\event\EventManager; use oat\oatbox\service\ServiceManager; +use oat\oatbox\service\ServiceNotFoundException; use oat\tao\model\service\InjectionAwareService; use oat\taoDelivery\model\execution\DeliveryServerService; use oat\taoQtiTest\models\classes\event\ResultTestVariablesTransmissionEvent; @@ -63,7 +65,7 @@ public function transmitResultTestVariable(ResultTestVariablesTransmissionEvent $event->getTestUri() ); - if (empty($this->containsScoreTotal($event))) { + if (!$this->containsScoreTotal($event)) { return; } @@ -90,8 +92,9 @@ public function getServiceLocator() } /** + * @return ReadableResultStorage + * @throws ServiceNotFoundException * @throws common_exception_Error - * @throws InvalidServiceManagerException */ private function getResultsStorage(): ReadableResultStorage { @@ -105,18 +108,16 @@ private function getResultsStorage(): ReadableResultStorage return $storage; } - /** - * @param ResultTestVariablesTransmissionEvent $event - * @return array - */ - private function containsScoreTotal(ResultTestVariablesTransmissionEvent $event): array + private function containsScoreTotal(ResultTestVariablesTransmissionEvent $event): bool { - return array_filter( + $scoreTotal = array_filter( $event->getVariables(), function ($item) { return $item->getIdentifier() === 'SCORE_TOTAL'; } ); + + return !empty($scoreTotal); } /**