/**
  * Write an AssessmetnItemSession from the current binary stream.
  * 
  * @param AssessmentTestSeeker $seeker The AssessmentTestSeeker object from where the position of components will be pulled out.
  * @param AssessmentItemSession $session An AssessmentItemSession object.
  * @throws QtiBinaryStreamAccessException
  */
 public function writeAssessmentItemSession(AssessmentTestSeeker $seeker, AssessmentItemSession $session)
 {
     try {
         $this->writeShort($seeker->seekPosition($session->getAssessmentItem()));
         $this->writeTinyInt($session->getState());
         $this->writeTinyInt($session->getNavigationMode());
         $this->writeTinyInt($session->getSubmissionMode());
         $this->writeBoolean($session->isAttempting());
         $isItemSessionControlDefault = $session->getItemSessionControl()->isDefault();
         if ($isItemSessionControlDefault === true) {
             $this->writeBoolean(false);
         } else {
             $this->writeBoolean(true);
             $this->writeShort($seeker->seekPosition($session->getItemSessionControl()));
         }
         if ($session->getState() !== AssessmentItemSessionState::NOT_SELECTED) {
             $this->writeTinyInt($session['numAttempts']->getValue());
             $this->writeDuration($session['duration']);
             $this->writeString($session['completionStatus']->getValue());
             if ($session['numAttempts']->getValue() > 0) {
                 $this->writeDateTime($session->getTimeReference());
             }
         }
         // minus the 3 built-in variables
         $varCount = count($session) - 3;
         $this->writeTinyInt($varCount);
         $itemOutcomes = $session->getAssessmentItem()->getOutcomeDeclarations();
         $itemResponses = $session->getAssessmentItem()->getResponseDeclarations();
         foreach ($session->getKeys() as $varId) {
             if (in_array($varId, array('numAttempts', 'duration', 'completionStatus')) === false) {
                 $var = $session->getVariable($varId);
                 $isOutcome = $var instanceof OutcomeVariable;
                 $variableDeclaration = $isOutcome === true ? $itemOutcomes[$varId] : $itemResponses[$varId];
                 try {
                     $this->writeBoolean($isOutcome);
                     $this->writeShort($seeker->seekPosition($variableDeclaration));
                     $this->writeVariableValue($var);
                 } catch (OutOfBoundsException $e) {
                     $msg = "No variable found in the assessmentTest tree structure.";
                     throw new QtiBinaryStreamAccessException($msg, $this, QtiBinaryStreamAccessException::ITEM_SESSION, $e);
                 }
             }
         }
     } catch (BinaryStreamAccessException $e) {
         $msg = "An error occured while writing an assessment item session.";
         throw new QtiBinaryStreamAccessException($msg, $this, QtiBinaryStreamAccessException::ITEM_SESSION, $e);
     } catch (OutOfBoundsException $e) {
         $msg = "No assessmentItemRef found in the assessmentTest tree structure.";
         throw new QtiBinaryStreamAccessException($msg, $this, QtiBinaryStreamAccessException::ITEM_SESSION, $e);
     }
 }
 public function testModalFeedback()
 {
     $doc = new XmlDocument('2.1.0');
     $doc->load(self::samplesDir() . 'ims/items/2_1/modalFeedback.xml');
     $itemSession = new AssessmentItemSession($doc->getDocumentComponent());
     $itemSessionControl = new ItemSessionControl();
     $itemSessionControl->setShowFeedback(true);
     $itemSessionControl->setMaxAttempts(0);
     $itemSession->setItemSessionControl($itemSessionControl);
     $itemSession->beginItemSession();
     $responses = new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new Identifier('true'))));
     $itemSession->beginAttempt();
     $itemSession->endAttempt($responses);
     $this->assertEquals('correct', $itemSession['FEEDBACK']->getValue());
     $this->assertEquals(AssessmentItemSessionState::MODAL_FEEDBACK, $itemSession->getState());
     // new attempt!
     $responses = new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new Identifier('false'))));
     $itemSession->beginAttempt();
     $itemSession->endAttempt($responses);
     $this->assertEquals('incorrect', $itemSession['FEEDBACK']->getValue());
     $this->assertEquals(AssessmentItemSessionState::MODAL_FEEDBACK, $itemSession->getState());
     $itemSession->endItemSession();
     $this->assertEquals('completed', $itemSession['completionStatus']->getValue());
 }
Esempio n. 3
0
 /**
  * Write an AssessmetnItemSession from the current binary stream.
  *
  * @param \qtism\runtime\storage\common\AssessmentTestSeeker $seeker The AssessmentTestSeeker object from where the position of components will be pulled out.
  * @param \qtism\runtime\tests\AssessmentItemSession $session An AssessmentItemSession object.
  * @throws \qtism\runtime\storage\binary\QtiBinaryStreamAccessException
  */
 public function writeAssessmentItemSession(AssessmentTestSeeker $seeker, AssessmentItemSession $session)
 {
     try {
         $this->writeShort($seeker->seekPosition($session->getAssessmentItem()));
         $this->writeTinyInt($session->getState());
         $this->writeTinyInt($session->getNavigationMode());
         $this->writeTinyInt($session->getSubmissionMode());
         $this->writeBoolean($session->isAttempting());
         $isItemSessionControlDefault = $session->getItemSessionControl()->isDefault();
         if ($isItemSessionControlDefault === true) {
             $this->writeBoolean(false);
         } else {
             $this->writeBoolean(true);
             $this->writeShort($seeker->seekPosition($session->getItemSessionControl()));
         }
         $this->writeTinyInt($session['numAttempts']->getValue());
         $this->writeDuration($session['duration']);
         $this->writeString($session['completionStatus']->getValue());
         $timeReference = $session->getTimeReference();
         if (is_null($timeReference) === true) {
             // Describe that we have no time reference for the session.
             $this->writeBoolean(false);
         } else {
             // Describe that we have a time reference for the session.
             $this->writeBoolean(true);
             // Write the time reference.
             $this->writeDateTime($timeReference);
         }
         // Write the session variables.
         // (minus the 3 built-in variables)
         $varCount = count($session) - 3;
         $this->writeTinyInt($varCount);
         $itemOutcomes = $session->getAssessmentItem()->getOutcomeDeclarations();
         $itemResponses = $session->getAssessmentItem()->getResponseDeclarations();
         $itemTemplates = $session->getAssessmentItem()->getTemplateDeclarations();
         foreach ($session->getKeys() as $varId) {
             if (in_array($varId, array('numAttempts', 'duration', 'completionStatus')) === false) {
                 $var = $session->getVariable($varId);
                 if ($var instanceof OutcomeVariable) {
                     $variableDeclaration = $itemOutcomes[$varId];
                     $variable = OutcomeVariable::createFromDataModel($variableDeclaration);
                     $varNature = 0;
                 } elseif ($var instanceof ResponseVariable) {
                     $variableDeclaration = $itemResponses[$varId];
                     $variable = ResponseVariable::createFromDataModel($variableDeclaration);
                     $varNature = 1;
                 } elseif ($var instanceof TemplateVariable) {
                     $variableDeclaration = $itemTemplates[$varId];
                     $variable = TemplateVariable::createFromDataModel($variableDeclaration);
                     $varNature = 2;
                 }
                 try {
                     $this->writeShort($varNature);
                     $this->writeShort($seeker->seekPosition($variableDeclaration));
                     // If defaultValue or correct response is different from what's inside
                     // the variable declaration, just write it.
                     $hasDefaultValue = !Utils::equals($variable->getDefaultValue(), $var->getDefaultValue());
                     $hasCorrectResponse = false;
                     if ($varNature === 1 && !Utils::equals($variable->getCorrectResponse(), $var->getCorrectResponse())) {
                         $hasCorrectResponse = true;
                     }
                     $this->writeBoolean($hasDefaultValue);
                     $this->writeBoolean($hasCorrectResponse);
                     $this->writeVariableValue($var, self::RW_VALUE);
                     if ($hasDefaultValue === true) {
                         $this->writeVariableValue($var, self::RW_DEFAULTVALUE);
                     }
                     if ($hasCorrectResponse === true) {
                         $this->writeVariableValue($var, self::RW_CORRECTRESPONSE);
                     }
                 } catch (OutOfBoundsException $e) {
                     $msg = "No variable found in the assessmentTest tree structure.";
                     throw new QtiBinaryStreamAccessException($msg, $this, QtiBinaryStreamAccessException::ITEM_SESSION, $e);
                 }
             }
         }
         // Write shuffling states if any.
         $shufflingStates = $session->getShufflingStates();
         $this->writeTinyInt(count($shufflingStates));
         foreach ($shufflingStates as $shufflingState) {
             $this->writeShufflingState($shufflingState);
         }
     } catch (BinaryStreamAccessException $e) {
         $msg = "An error occured while writing an assessment item session.";
         throw new QtiBinaryStreamAccessException($msg, $this, QtiBinaryStreamAccessException::ITEM_SESSION, $e);
     } catch (OutOfBoundsException $e) {
         $msg = "No assessmentItemRef found in the assessmentTest tree structure.";
         throw new QtiBinaryStreamAccessException($msg, $this, QtiBinaryStreamAccessException::ITEM_SESSION, $e);
     }
 }