/**
  * Add an AssessmentItemSession to the store, for a given $occurence number.
  *
  * @param \qtism\runtime\tests\AssessmentItemSession $assessmentItemSession
  * @param integer $occurence The occurence number of the session.
  */
 public function addAssessmentItemSession(AssessmentItemSession $assessmentItemSession, $occurence = 0)
 {
     $assessmentItemRef = $assessmentItemSession->getAssessmentItem();
     if (isset($this->shelves[$assessmentItemRef]) === false) {
         $this->shelves[$assessmentItemRef] = new AssessmentItemSessionCollection();
     }
     $this->shelves[$assessmentItemRef][$occurence] = $assessmentItemSession;
 }
 /**
  * Add an item session to the current assessment test session.
  * 
  * @param AssessmentItemSession $session
  * @throws LogicException If the AssessmentItemRef object bound to $session is unknown by the AssessmentTestSession.
  */
 protected function addItemSession(AssessmentItemSession $session, $occurence = 0)
 {
     $assessmentItemRefs = $this->getAssessmentItemRefs();
     $sessionAssessmentItemRefIdentifier = $session->getAssessmentItem()->getIdentifier();
     if ($this->getAssessmentItemRefs()->contains($session->getAssessmentItem()) === false) {
         // The session that is requested to be set is bound to an item
         // which is not referenced in the test. This is a pure logic error.
         $msg = "The item session to set is bound to an unknown AssessmentItemRef.";
         throw new LogicException($msg);
     }
     $this->getAssessmentItemSessionStore()->addAssessmentItemSession($session, $occurence);
 }
 /**
  * AssessmentTestSession implementations must override this method in order
  * to submit item results from a given $assessmentItemSession to the appropriate
  * data source.
  *
  * This method is triggered each time response processing takes place.
  *
  * @param AssessmentItemSession $itemSession The lastly updated AssessmentItemSession.
  * @param integer $occurrence The occurrence number of the item bound to $assessmentItemSession.
  * @throws AssessmentTestSessionException With error code RESULT_SUBMISSION_ERROR if an error occurs while transmitting results.
  */
 public function submitItemResults(AssessmentItemSession $itemSession, $occurrence = 0)
 {
     $itemRef = $itemSession->getAssessmentItem();
     $identifier = $itemRef->getIdentifier();
     $duration = $this->getTimerDuration($identifier);
     $itemDurationVar = $itemSession->getVariable('duration');
     $sessionDuration = $itemDurationVar->getValue();
     \common_Logger::i("Force duration of item '{$identifier}' to {$duration} instead of {$sessionDuration}");
     $itemSession->getVariable('duration')->setValue($duration);
     parent::submitItemResults($itemSession, $occurrence);
 }
 protected function submitItemResults(AssessmentItemSession $assessmentItemSession, $occurence = 0)
 {
     foreach ($assessmentItemSession as $id => $var) {
         $this->addItemResultResult($assessmentItemSession->getAssessmentItem()->getIdentifier() . '.' . $occurence . '.' . $id, $var->getValue());
     }
 }
 /**
  * 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);
     }
 }
Esempio n. 6
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);
     }
 }
 /**
  * Checks if an item has been completed
  * @param RouteItem $routeItem
  * @param AssessmentItemSession $itemSession
  * @return bool
  */
 public static function isItemCompleted(RouteItem $routeItem, AssessmentItemSession $itemSession)
 {
     $completed = false;
     if ($routeItem->getTestPart()->getNavigationMode() === NavigationMode::LINEAR) {
         // In linear mode, we consider the item completed if it was presented.
         if ($itemSession->isPresented() === true) {
             $completed = true;
         }
     } else {
         // In nonlinear mode we consider:
         // - an adaptive item completed if it's completion status is 'completed'.
         // - a non-adaptive item to be completed if it is responded.
         $isAdaptive = $itemSession->getAssessmentItem()->isAdaptive();
         if ($isAdaptive === true && $itemSession['completionStatus']->getValue() === AssessmentItemSession::COMPLETION_STATUS_COMPLETED) {
             $completed = true;
         } else {
             if ($isAdaptive === false && $itemSession->isResponded() === true) {
                 $completed = true;
             }
         }
     }
     return $completed;
 }