/**
  * Resolve the given TAO Item URI in the path to
  * the related QTI-XML file.
  * 
  * @param string $url The URI of the TAO Item to resolve.
  * @return string The path to the related QTI-XML file.
  * @throws ResolutionException If an error occurs during the resolution of $url.
  */
 public function resolve($url)
 {
     $taoItem = new core_kernel_classes_Resource($url);
     if ($taoItem->exists() === false) {
         $msg = "The QTI Item with URI '{$url}' cannot be found.";
         throw new ResolutionException($msg);
     }
     // The item is retrieved from the database.
     // We can try to reach the QTI-XML file by detecting
     // where it is supposed to be located.
     return QtiFile::getQtiFilePath(new core_kernel_classes_Resource($url));
 }
 /**
  * Item's ResponseProcessing.
  *
  * @param core_kernel_classes_Resource $item The Item you want to apply ResponseProcessing.
  * @throws \RuntimeException If an error occurs while processing responses or transmitting results
  */
 protected function processResponses(core_kernel_classes_Resource $item)
 {
     $jsonPayload = taoQtiCommon_helpers_Utils::readJsonPayload();
     try {
         $qtiXmlFilePath = QtiFile::getQtiFilePath($item);
         $qtiXmlDoc = new XmlDocument();
         $qtiXmlDoc->load($qtiXmlFilePath);
     } catch (StorageException $e) {
         $msg = "An error occurred while loading QTI-XML file at expected location '{$qtiXmlFilePath}'.";
         common_Logger::e($e->getPrevious()->getMessage());
         throw new \RuntimeException($msg, 0, $e);
     }
     $itemSession = new AssessmentItemSession($qtiXmlDoc->getDocumentComponent(), new SessionManager());
     $itemSession->beginItemSession();
     $variables = array();
     $filler = new taoQtiCommon_helpers_PciVariableFiller($qtiXmlDoc->getDocumentComponent());
     // Convert client-side data as QtiSm Runtime Variables.
     foreach ($jsonPayload as $id => $response) {
         try {
             $var = $filler->fill($id, $response);
             // Do not take into account QTI Files at preview time.
             // Simply delete the created file.
             if (taoQtiCommon_helpers_Utils::isQtiFile($var, false) === true) {
                 $fileManager = taoQtiCommon_helpers_Utils::getFileDatatypeManager();
                 $fileManager->delete($var->getValue());
             } else {
                 $variables[] = $var;
             }
         } catch (OutOfRangeException $e) {
             // A variable value could not be converted, ignore it.
             // Developer's note: QTI Pairs with a single identifier (missing second identifier of the pair) are transmitted as an array of length 1,
             // this might cause problem. Such "broken" pairs are simply ignored.
             common_Logger::d("Client-side value for variable '{$id}' is ignored due to data malformation.");
         } catch (OutOfBoundsException $e) {
             // No such identifier found in item.
             common_Logger::d("The variable with identifier '{$id}' is not declared in the item definition.");
         }
     }
     try {
         $itemSession->beginAttempt();
         $itemSession->endAttempt(new State($variables));
         // Return the item session state to the client-side.
         echo json_encode(array('success' => true, 'displayFeedback' => true, 'itemSession' => self::buildOutcomeResponse($itemSession)));
     } catch (AssessmentItemSessionException $e) {
         $msg = "An error occurred while processing the responses.";
         throw new \RuntimeException($msg, 0, $e);
     } catch (taoQtiCommon_helpers_ResultTransmissionException $e) {
         $msg = "An error occurred while transmitting a result to the target Result Server.";
         throw new \RuntimeException($msg, 0, $e);
     }
 }
 /**
  * Resolve the given TAO Item URI in the path to
  * the related QTI-XML file.
  * 
  * @param string $url The URI of the TAO Item to resolve.
  * @return string The path to the related QTI-XML file.
  * @throws ResolutionException If an error occurs during the resolution of $url.
  */
 public function resolve($url)
 {
     $taoItem = new core_kernel_classes_Resource($url);
     if ($taoItem->exists() === false) {
         $msg = "The QTI Item with URI '{$url}' cannot be found.";
         throw new ResolutionException($msg);
     }
     // The item is retrieved from the database.
     // We can try to reach the QTI-XML file by detecting
     // where it is supposed to be located.
     // strip xinclude, we don't need that at the moment.
     $file = QtiFile::getQtiFilePath(new core_kernel_classes_Resource($url));
     $tmpfile = sys_get_temp_dir() . '/' . md5($url) . '.xml';
     $raw = file_get_contents($file);
     $raw = preg_replace("/<xi:include(?:.*)>/u", '', $raw);
     file_put_contents($tmpfile, $raw);
     return $tmpfile;
 }
 /**
  * Item's ResponseProcessing.
  * 
  * @param core_kernel_file_File $itemPath The Item file resource you want to apply ResponseProcessing.
  * @throws RuntimeException If an error occurs while processing responses or transmitting results
  */
 protected function processResponses(core_kernel_classes_Resource $item)
 {
     $jsonPayload = taoQtiCommon_helpers_Utils::readJsonPayload();
     try {
         $qtiXmlFileContent = QtiFile::getQtiFileContent($item);
         $qtiXmlDoc = new XmlDocument();
         $qtiXmlDoc->loadFromString($qtiXmlFileContent);
     } catch (StorageException $e) {
         $msg = "An error occured while loading QTI-XML file at expected location '{$qtiXmlFilePath}'.";
         throw new \RuntimeException($msg, 0, $e);
     }
     $itemSession = new AssessmentItemSession($qtiXmlDoc->getDocumentComponent(), new SessionManager());
     $itemSession->beginItemSession();
     $variables = array();
     // Convert client-side data as QtiSm Runtime Variables.
     foreach ($jsonPayload as $identifier => $response) {
         $filler = new taoQtiCommon_helpers_PciVariableFiller($qtiXmlDoc->getDocumentComponent());
         try {
             $var = $filler->fill($identifier, $response);
             // Do not take into account QTI File placeholders.
             if (taoQtiCommon_helpers_Utils::isQtiFilePlaceHolder($var) === false) {
                 $variables[] = $var;
             }
         } catch (\OutOfRangeException $e) {
             // A variable value could not be converted, ignore it.
             // Developer's note: QTI Pairs with a single identifier (missing second identifier of the pair) are transmitted as an array of length 1,
             // this might cause problem. Such "broken" pairs are simply ignored.
             common_Logger::d("Client-side value for variable '{$identifier}' is ignored due to data malformation.");
         } catch (\OutOfBoundsException $e) {
             // The response identifier does not match any response declaration.
             common_Logger::d("Uknown item variable declaration '{$identifier}.");
         }
     }
     try {
         $itemSession->beginAttempt();
         $itemSession->endAttempt(new State($variables));
         // Transmit results to the Result Server.
         $this->transmitResults($item, $itemSession);
         // Return the item session state to the client-side.
         echo json_encode(array('success' => true, 'displayFeedback' => true, 'itemSession' => self::buildOutcomeResponse($itemSession), 'feedbacks' => $this->getFeedbacks($itemSession)));
     } catch (AssessmentItemSessionException $e) {
         $msg = "An error occured while processing the responses.";
         throw new \RuntimeException($msg, 0, $e);
     } catch (taoQtiCommon_helpers_ResultTransmissionException $e) {
         $msg = "An error occured while transmitting variable '{$identifier}' to the target Result Server.";
         throw new \RuntimeException($msg, 0, $e);
     }
 }