public function tearDown()
 {
     parent::tearDown();
     $fileManager = taoQtiCommon_helpers_Utils::getFileDatatypeManager();
     $file = $this->getFile();
     $fileManager->delete($file);
 }
 /**
  * Fill the variable $variableName with a correctly transformed $clientSideValue.
  *
  * @param string $variableName The variable identifier you want to fill.
  * @param array $clientSideValue The value received from the client-side representing the value of the variable with identifier $variableName.
  * @return Variable A Variable object filled with a correctly transformed $clientSideValue.
  * @throws OutOfBoundsException If no variable with $variableName is described in the item.
  * @throws OutOfRangeException If the $clientSideValue does not fit the target variable's baseType.
  */
 public function fill($variableName, $clientSideValue)
 {
     $variableDeclaration = $this->findVariableDeclaration($variableName);
     if ($variableDeclaration === false) {
         $itemId = $this->getItemRef()->getIdentifier();
         $msg = "Variable declaration with identifier '{$variableName}' not found in item '{$itemId}'.";
         throw new OutOfBoundsException($msg);
     }
     // Create Runtime Variable from Data Model.
     $runtimeVar = $variableDeclaration instanceof ResponseDeclaration ? ResponseVariable::createFromDataModel($variableDeclaration) : OutcomeVariable::createFromDataModel($variableDeclaration);
     // Set the data into the runtime variable thanks to the PCI JSON Unmarshaller
     // from QTISM.
     try {
         $unmarshaller = new PciJsonUnmarshaller(taoQtiCommon_helpers_Utils::getFileDatatypeManager());
         $value = $unmarshaller->unmarshall($clientSideValue);
         // Dev's note:
         // The PCI JSON Representation format does make the difference between multiple and ordered containers.
         // We then have to juggle a bit if the target variable has ordered cardinality.
         if ($value !== null && $value->getCardinality() === Cardinality::MULTIPLE && $variableDeclaration->getCardinality() === Cardinality::ORDERED) {
             $value = new OrderedContainer($value->getBaseType(), $value->getArrayCopy());
         }
         $runtimeVar->setValue($value);
     } catch (PciJsonUnmarshallingException $e) {
         $strClientSideValue = mb_substr(var_export($clientSideValue, true), 0, 50, TAO_DEFAULT_ENCODING);
         $msg = "Unable to put value '{$strClientSideValue}' into variable '{$variableName}'.";
         throw new OutOfRangeException($msg, 0, $e);
     }
     return $runtimeVar;
 }
Beispiel #3
0
 /**
  * @dataProvider toQtiDatatypeProvider
  */
 public function testToQtiDatatype($cardinality, $basetype, $value, $expected)
 {
     $result = taoQtiCommon_helpers_Utils::toQtiDatatype($cardinality, $basetype, $value);
     if ($expected === null) {
         $this->assertNull($result);
     } elseif ($expected instanceof QtiDatatype) {
         $this->assertTrue($expected->equals($result), $expected . ' != ' . $result);
     } else {
         $this->fail('testToQtiDatatype only deals with QtiDatatype objects or null.');
     }
 }
 /**
  * Transform a QTI Datatype value to a value compliant
  * with result server.
  * 
  * @param mixed $value
  * @return string
  */
 private static function transformValue($value)
 {
     if (gettype($value) === 'object') {
         if ($value instanceof File) {
             return taoQtiCommon_helpers_Utils::qtiFileToString($value);
         } else {
             return $value->__toString();
         }
     } else {
         return $value;
     }
 }
 /**
  * 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);
     }
 }
 /**
  * Manage the bidirectional communication
  */
 public function messages()
 {
     // close the PHP session to prevent session overwriting and loss of security token for secured queries
     session_write_close();
     $code = 200;
     try {
         $input = \taoQtiCommon_helpers_Utils::readJsonPayload();
         if (!$input) {
             $input = [];
         }
         $serviceContext = $this->getServiceContext(false, false);
         /* @var $communicationService \oat\taoQtiTest\models\runner\communicator\CommunicationService */
         $communicationService = $this->getServiceManager()->get(QtiCommunicationService::CONFIG_ID);
         $response = ['responses' => $communicationService->processInput($serviceContext, $input), 'messages' => $communicationService->processOutput($serviceContext), 'success' => true];
     } catch (common_Exception $e) {
         $response = $this->getErrorResponse($e);
         $code = $this->getErrorCode($e);
     }
     $this->returnJson($response, $code, false);
 }