/** * 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); } }