/**
  * @dataProvider fillVariableProvider
  * 
  * @param IAssessmentItem $itemRef The reference item.
  * @param string $variableIdentifier The identifier of the variable.
  * @param array $data Client-side data.
  * @param Variable $expectedVariable
  */
 public function testFillVariable(array $data, Variable $expectedVariable)
 {
     // Non-time dependent basic item in 'Yoda English'.
     $itemRef = new AssessmentItem('Q01', 'Question 01', false, 'en-YO');
     $outcomeDeclarations = new OutcomeDeclarationCollection();
     $outcomeDeclarations[] = new OutcomeDeclaration('OUTCOME1', BaseType::FLOAT, Cardinality::SINGLE);
     $outcomeDeclarations[] = new OutcomeDeclaration('OUTCOME2', BaseType::INTEGER, Cardinality::SINGLE);
     $outcomeDeclarations[] = new OutcomeDeclaration('OUTCOME3', BaseType::BOOLEAN, Cardinality::SINGLE);
     $outcomeDeclarations[] = new OutcomeDeclaration('OUTCOME4', BaseType::STRING, Cardinality::SINGLE);
     $outcomeDeclarations[] = new OutcomeDeclaration('OUTCOME5', BaseType::POINT, Cardinality::SINGLE);
     $outcomeDeclarations[] = new OutcomeDeclaration('OUTCOME6', BaseType::PAIR, Cardinality::SINGLE);
     $outcomeDeclarations[] = new OutcomeDeclaration('OUTCOME7', BaseType::DIRECTED_PAIR, Cardinality::SINGLE);
     $outcomeDeclarations[] = new OutcomeDeclaration('OUTCOME8', BaseType::DURATION, Cardinality::SINGLE);
     $outcomeDeclarations[] = new OutcomeDeclaration('OUTCOME9', BaseType::URI, Cardinality::SINGLE);
     $outcomeDeclarations[] = new OutcomeDeclaration('OUTCOME10', BaseType::IDENTIFIER, Cardinality::SINGLE);
     $outcomeDeclarations[] = new OutcomeDeclaration('OUTCOME11', BaseType::INT_OR_IDENTIFIER, Cardinality::SINGLE);
     $outcomeDeclarations[] = new OutcomeDeclaration('OUTCOME12', BaseType::INTEGER, Cardinality::SINGLE);
     $responseDeclarations = new ResponseDeclarationCollection();
     $responseDeclarations[] = new ResponseDeclaration('RESPONSE1', BaseType::IDENTIFIER, Cardinality::SINGLE);
     $responseDeclarations[] = new ResponseDeclaration('RESPONSE2', BaseType::IDENTIFIER, Cardinality::MULTIPLE);
     $responseDeclarations[] = new ResponseDeclaration('RESPONSE3', BaseType::DIRECTED_PAIR, Cardinality::ORDERED);
     $responseDeclarations[] = new ResponseDeclaration('RESPONSE4', -1, Cardinality::RECORD);
     $responseDeclarations[] = new ResponseDeclaration('RESPONSE5', -1, Cardinality::RECORD);
     $responseDeclarations[] = new ResponseDeclaration('RESPONSE6', -1, Cardinality::RECORD);
     $responseDeclarations[] = new ResponseDeclaration('RESPONSE7', -1, Cardinality::RECORD);
     $responseDeclarations[] = new ResponseDeclaration('RESPONSE8', BaseType::BOOLEAN, Cardinality::MULTIPLE);
     $itemRef->setOutcomeDeclarations($outcomeDeclarations);
     $itemRef->setResponseDeclarations($responseDeclarations);
     $filler = new taoQtiCommon_helpers_PciVariableFiller($itemRef);
     $variable = $filler->fill($expectedVariable->getIdentifier(), $data);
     $this->assertEquals($expectedVariable->getIdentifier(), $variable->getIdentifier());
     $this->assertEquals($expectedVariable->getBaseType(), $variable->getBaseType());
     $this->assertEquals($expectedVariable->getCardinality(), $variable->getCardinality());
     $this->assertEquals(get_class($expectedVariable), get_class($variable));
     if ($expectedVariable->getValue() === null) {
         $this->assertSame($expectedVariable->getValue(), $variable->getValue());
     } else {
         $this->assertTrue($expectedVariable->getValue()->equals($variable->getValue()));
     }
 }
 /**
  * Action called when a QTI Item embedded in a QTI Test submit responses.
  * 
  */
 public function storeItemVariableSet()
 {
     if ($this->beforeAction()) {
         // --- Deal with provided responses.
         $jsonPayload = taoQtiCommon_helpers_Utils::readJsonPayload();
         $responses = new State();
         $currentItem = $this->getTestSession()->getCurrentAssessmentItemRef();
         $currentOccurence = $this->getTestSession()->getCurrentAssessmentItemRefOccurence();
         if ($currentItem === false) {
             $msg = "Trying to store item variables but the state of the test session is INITIAL or CLOSED.\n";
             $msg .= "Session state value: " . $this->getTestSession()->getState() . "\n";
             $msg .= "Session ID: " . $this->getTestSession()->getSessionId() . "\n";
             $msg .= "JSON Payload: " . mb_substr(json_encode($jsonPayload), 0, 1000);
             common_Logger::e($msg);
         }
         $filler = new taoQtiCommon_helpers_PciVariableFiller($currentItem);
         if (is_array($jsonPayload)) {
             foreach ($jsonPayload as $id => $response) {
                 try {
                     $var = $filler->fill($id, $response);
                     // Do not take into account QTI File placeholders.
                     if (taoQtiCommon_helpers_Utils::isQtiFilePlaceHolder($var) === false) {
                         $responses->setVariable($var);
                     }
                 } catch (OutOfRangeException $e) {
                     common_Logger::d("Could not convert client-side value for variable '{$id}'.");
                 } catch (OutOfBoundsException $e) {
                     common_Logger::d("Could not find variable with identifier '{$id}' in current item.");
                 }
             }
         } else {
             common_Logger::e('Invalid json payload');
         }
         $displayFeedback = $this->getTestSession()->getCurrentSubmissionMode() !== SubmissionMode::SIMULTANEOUS;
         $stateOutput = new taoQtiCommon_helpers_PciStateOutput();
         try {
             common_Logger::i('Responses sent from the client-side. The Response Processing will take place.');
             $this->getTestSession()->endAttempt($responses, true);
             // Return the item session state to the client side.
             $itemSession = $this->getTestSession()->getAssessmentItemSessionStore()->getAssessmentItemSession($currentItem, $currentOccurence);
             foreach ($itemSession->getAllVariables() as $var) {
                 $stateOutput->addVariable($var);
             }
             $itemCompilationDirectory = $this->getDirectory($this->getRequestParameter('itemDataPath'));
             $jsonReturn = array('success' => true, 'displayFeedback' => $displayFeedback, 'itemSession' => $stateOutput->getOutput(), 'feedbacks' => array());
             if ($displayFeedback === true) {
                 $jsonReturn['feedbacks'] = QtiRunner::getFeedbacks($itemCompilationDirectory, $itemSession);
             }
             echo json_encode($jsonReturn);
         } catch (AssessmentTestSessionException $e) {
             $this->handleAssessmentTestSessionException($e);
         }
         $this->afterAction(false);
     }
 }