/** * Create a new SessionManager object. * * @param taoResultServer_models_classes_ResultServerStateFull $resultServer The ResultServer to be set to the AssessmentTestSession to be built. * @param core_kernel_classes_Resource $test The TAO Resource describing the Test definition to be set to the AssessmentTestSession to be built. */ public function __construct(taoResultServer_models_classes_ResultServerStateFull $resultServer, core_kernel_classes_Resource $test) { parent::__construct(); $this->setAcceptableLatency(new QtiDuration(taoQtiTest_models_classes_QtiTestService::singleton()->getQtiTestAcceptableLatency())); $this->setResultServer($resultServer); $this->setTest($test); }
/** * Read an AssessmentItemSession from the current binary stream. * * @param AbstractSessionManager $manager * @param AssessmentTestSeeker $seeker An AssessmentTestSeeker object from where 'assessmentItemRef', 'outcomeDeclaration' and 'responseDeclaration' QTI components will be pulled out. * @throws QtiBinaryStreamAccessException */ public function readAssessmentItemSession(AbstractSessionManager $manager, AssessmentTestSeeker $seeker) { try { $itemRefPosition = $this->readShort(); $assessmentItemRef = $seeker->seekComponent('assessmentItemRef', $itemRefPosition); $session = $manager->createAssessmentItemSession($assessmentItemRef); $session->setAssessmentItem($assessmentItemRef); $session->setState($this->readTinyInt()); $session->setNavigationMode($this->readTinyInt()); $session->setSubmissionMode($this->readTinyInt()); // The is-attempting field was added in Binary Storage v2. if (QtiBinaryConstants::QTI_BINARY_STORAGE_VERSION >= 2) { $session->setAttempting($this->readBoolean()); } if ($this->readBoolean() === true) { $itemSessionControl = $seeker->seekComponent('itemSessionControl', $this->readShort()); $session->setItemSessionControl($itemSessionControl); } if ($session->getState() !== AssessmentItemSessionState::NOT_SELECTED) { $session['numAttempts'] = new Integer($this->readTinyInt()); $session['duration'] = $this->readDuration(); $session['completionStatus'] = new Identifier($this->readString()); if ($session['numAttempts']->getValue() > 0) { $session->setTimeReference($this->readDateTime()); } } $varCount = $this->readTinyInt(); for ($i = 0; $i < $varCount; $i++) { $isOutcome = $this->readBoolean(); $varPosition = $this->readShort(); $variable = null; try { $variable = $seeker->seekComponent($isOutcome === true ? 'outcomeDeclaration' : 'responseDeclaration', $varPosition); } catch (OutOfBoundsException $e) { $msg = "No variable found at position {$varPosition} in the assessmentTest tree structure."; throw new QtiBinaryStreamAccessException($msg, $this, QtiBinaryStreamAccessException::ITEM_SESSION, $e); } $variable = $variable instanceof OutcomeDeclaration ? OutcomeVariable::createFromDataModel($variable) : ResponseVariable::createFromDataModel($variable); // If we are here, we have our variable. $this->readVariableValue($variable); $session->setVariable($variable); } return $session; } catch (BinaryStreamAccessException $e) { $msg = "An error occured while reading an assessment item session."; throw new QtiBinaryStreamAccessException($msg, $this, QtiBinaryStreamAccessException::ITEM_SESSION, $e); } catch (OutOfBoundsException $e) { $msg = "No assessmentItemRef found at position {$itemRefPosition} in the assessmentTest tree structure."; throw new QtiBinaryStreamAccessException($msg, $this, QtiBinaryStreamAccessException::ITEM_SESSION, $e); } }
/** * Read an AssessmentItemSession from the current binary stream. * * @param \qtism\runtime\tests\AbstractSessionManager $manager * @param \qtism\runtime\storage\common\AssessmentTestSeeker $seeker An AssessmentTestSeeker object from where 'assessmentItemRef', 'outcomeDeclaration' and 'responseDeclaration' QTI components will be pulled out. * @throws \qtism\runtime\storage\binary\QtiBinaryStreamAccessException */ public function readAssessmentItemSession(AbstractSessionManager $manager, AssessmentTestSeeker $seeker) { try { $itemRefPosition = $this->readShort(); $assessmentItemRef = $seeker->seekComponent('assessmentItemRef', $itemRefPosition); $session = $manager->createAssessmentItemSession($assessmentItemRef); $session->setAssessmentItem($assessmentItemRef); $session->setState($this->readTinyInt()); $session->setNavigationMode($this->readTinyInt()); $session->setSubmissionMode($this->readTinyInt()); $session->setAttempting($this->readBoolean()); if ($this->readBoolean() === true) { $itemSessionControl = $seeker->seekComponent('itemSessionControl', $this->readShort()); $session->setItemSessionControl($itemSessionControl); } $session['numAttempts'] = new QtiInteger($this->readTinyInt()); $session['duration'] = $this->readDuration(); $session['completionStatus'] = new QtiIdentifier($this->readString()); if ($this->readBoolean() === true) { // A time reference is set. $session->setTimeReference($this->readDateTime()); } // Read the number of item-specific variables involved in the session. $varCount = $this->readTinyInt(); for ($i = 0; $i < $varCount; $i++) { // For each of these variables... // Detect the nature of the variable // 0 = outcomeVariable, 1 = responseVariable, 2 = templateVariable $varNature = $this->readShort(); // Read the position of the associated variableDeclaration // in the assessment tree. $varPosition = $this->readShort(); $variable = null; try { if ($varNature === 0) { // outcome $variable = $seeker->seekComponent('outcomeDeclaration', $varPosition); $variable = OutcomeVariable::createFromDataModel($variable); } elseif ($varNature === 1) { // response $variable = $seeker->seekComponent('responseDeclaration', $varPosition); $variable = ResponseVariable::createFromDataModel($variable); } elseif ($varNature === 2) { // template $variable = $seeker->seekComponent('templateDeclaration', $varPosition); $variable = TemplateVariable::createFromDataModel($variable); } } catch (OutOfBoundsException $e) { $msg = "No variable found at position {$varPosition} in the assessmentTest tree structure."; throw new QtiBinaryStreamAccessException($msg, $this, QtiBinaryStreamAccessException::ITEM_SESSION, $e); } // If we are here, we have our variable. We can read its value(s). // Do we have a specific default value? A specific correct response? $hasDefaultValue = $this->readBoolean(); $hasCorrectResponse = $this->readBoolean(); // Read the intrinsic value of the variable. $this->readVariableValue($variable, self::RW_VALUE); if ($hasDefaultValue === true) { $this->readVariableValue($variable, self::RW_DEFAULTVALUE); } if ($hasCorrectResponse === true) { $this->readVariableValue($variable, self::RW_CORRECTRESPONSE); } $session->setVariable($variable); } // Read shuffling states if any. $shufflingStateCount = $this->readTinyInt(); $shufflingStates = new ShufflingCollection(); for ($i = 0; $i < $shufflingStateCount; $i++) { $shufflingStates[] = $this->readShufflingState(); } $session->setShufflingStates($shufflingStates); return $session; } catch (BinaryStreamAccessException $e) { $msg = "An error occured while reading an assessment item session."; throw new QtiBinaryStreamAccessException($msg, $this, QtiBinaryStreamAccessException::ITEM_SESSION, $e); } catch (OutOfBoundsException $e) { $msg = "No assessmentItemRef found at position {$itemRefPosition} in the assessmentTest tree structure."; throw new QtiBinaryStreamAccessException($msg, $this, QtiBinaryStreamAccessException::ITEM_SESSION, $e); } }