public function testAssigningScoresAndCorrectResponses() { $doc = new XmlDocument(); $doc->load(self::samplesDir() . 'custom/items/template_processing.xml'); $session = new AssessmentItemSession($doc->getDocumentComponent()); $itemSessionControl = new ItemSessionControl(); $itemSessionControl->setMaxAttempts(0); $session->setItemSessionControl($itemSessionControl); $session->beginItemSession(); // Check that the templateProcessing was correctly processed. $this->assertEquals('ChoiceA', $session->getVariable('RESPONSE')->getCorrectResponse()->getValue()); $this->assertEquals(1.0, $session['GOODSCORE']->getValue()); $this->assertEquals(0.0, $session['WRONGSCORE']->getValue()); // Check that it really works... // With a correct response. $session->beginAttempt(); $responses = new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new QtiIdentifier('ChoiceA')))); $session->endAttempt($responses); $this->assertEquals(1.0, $session['SCORE']->getValue()); // With an incorrect response. $session->beginAttempt(); $responses = new State(array(new ResponseVariable('RESPONSE', Cardinality::SINGLE, BaseType::IDENTIFIER, new QtiIdentifier('ChoiceB')))); $session->endAttempt($responses); $this->assertEquals(0.0, $session['SCORE']->getValue()); }
public function testSeparateStylesheetTwo() { // The loaded component is still a rubricBlock but this // time with two (YES, TWO!) stylesheets. $doc = new XmlDocument('2.1'); $doc->load(self::samplesDir() . 'rendering/rubricblock_3.xml'); $this->assertEquals(2, count($doc->getDocumentComponent()->getStylesheets())); $renderingEngine = new XhtmlRenderingEngine(); $renderingEngine->setStylesheetPolicy(XhtmlRenderingEngine::STYLESHEET_SEPARATE); $rendering = $renderingEngine->render($doc->getDocumentComponent()); $linkElts = $rendering->getElementsByTagName('link'); $this->assertEquals(0, $linkElts->length); $linksFragment = $renderingEngine->getStylesheets(); $this->assertInstanceOf('\\DOMDocumentFragment', $linksFragment); $this->assertEquals(2, $linksFragment->childNodes->length); // Test first <link> element. $linkElt = $linksFragment->childNodes->item(0); $this->assertEquals('link', $linkElt->localName); $this->assertEquals('style1.css', $linkElt->getAttribute('href')); $this->assertEquals('text/css', $linkElt->getAttribute('type')); $this->assertEquals('screen', $linkElt->getAttribute('media')); $this->assertEquals('\\0_ !HOURRAY! _0/', $linkElt->getAttribute('title')); // Test second <link> element. $linkElt = $linksFragment->childNodes->item(1); $this->assertEquals('link', $linkElt->localName); $this->assertEquals('style2.css', $linkElt->getAttribute('href')); $this->assertEquals('text/css', $linkElt->getAttribute('type')); $this->assertEquals('screen', $linkElt->getAttribute('media')); $this->assertEquals('0/*\\0 (Jedi duel)', $linkElt->getAttribute('title')); }
public function parse($xmlString, $validate = true) { // TODO: Remove this, and move it higher up LogService::flush(); $xmlDocument = new XmlDocument(); if ($validate === false) { LogService::log('QTI pre-validation is turned off, some invalid attributes might be stripped from XML content upon conversion'); } $xmlDocument->loadFromString($xmlString, $validate); /** @var AssessmentItem $assessmentItem */ $assessmentTest = $xmlDocument->getDocumentComponent(); if (!$assessmentTest instanceof AssessmentTest) { throw new MappingException('XML is not a valid <assessmentItem> document'); } // Ignore `testPart` and `assessmentSection`. Grab every item references and merge in array $itemReferences = []; foreach ($assessmentTest->getComponentsByClassName('assessmentItemRef', true) as $assessmentItemRef) { $itemReferences[] = $assessmentItemRef->getIdentifier(); } LogService::log('Support for mapping is very limited. Elements such `testPart`, `assessmentSections`, `seclection`, `rubricBlock`, ' . 'etc are ignored. Please see developer docs for more details'); $data = new activity_data(); $data->set_items($itemReferences); $activity = new activity($assessmentTest->getIdentifier(), $data); // Flush out all the error messages stored in this static class, also ensure they are unique $messages = array_values(array_unique(LogService::flush())); return [$activity, $messages]; }
/** * Test {@link taoQtiTest_models_classes_QtiTestConverter::fromJson} * @dataProvider dataProvider * * @param string $testPath * @param string $json */ public function testFromJson($testPath, $json) { $doc = new XmlDocument('2.1'); $converter = new taoQtiTest_models_classes_QtiTestConverter($doc); $converter->fromJson($json); $result = preg_replace(array('/ {2,}/', '/<!--.*?-->|\\t|(?:\\r?\\n[ \\t]*)+/s'), array(' ', ''), $doc->saveToString()); $expected = preg_replace(array('/ {2,}/', '/<!--.*?-->|\\t|(?:\\r?\\n[ \\t]*)+/s'), array(' ', ''), file_get_contents($testPath)); $this->assertEquals($result, $expected); }
public function testGetShuffledChoiceIdentifierAtInvalidShuffledChoiceIndex() { $doc = new XmlDocument(); $doc->load(self::samplesDir() . 'ims/items/2_1/choice_fixed.xml'); $session = new AssessmentItemSession($doc->getDocumentComponent()); $session->beginItemSession(); $this->setExpectedException('\\OutOfBoundsException', 'No identifier at index 1337.'); $session->getShuffledChoiceIdentifierAt(0, 1337); }
public function testTimeLimits() { $doc = new XmlDocument(); $doc->load(self::samplesDir() . 'custom/runtime/timelimits.xml'); $testPart = $doc->getDocumentComponent()->getComponentByIdentifier('testPartId'); $this->assertTrue($testPart->hasTimeLimits()); $timeLimits = $testPart->getTimeLimits(); $this->assertTrue($timeLimits->getMinTime()->equals(new Duration('PT60S'))); $this->assertTrue($timeLimits->getMaxTime()->equals(new Duration('PT120S'))); $this->assertTrue($timeLimits->doesAllowLateSubmission()); }
public function testMappingMcqQuestion() { $questionJson = $this->getFixtureFileContents('learnosityjsons/item_mcq.json'); $question = json_decode($questionJson, true); list($xmlString, $messages) = Converter::convertLearnosityToQtiItem($question); $this->assertNotNull($xmlString); $this->assertTrue(StringUtil::startsWith($xmlString, '<?xml version="1.0" encoding="UTF-8"?> <assessmentItem xmlns="http://www.imsglobal.org/xsd/imsqti_v2p1"')); $document = new XmlDocument(); $document->loadFromString($xmlString); $this->assertNotNull($document); }
public function testItemSessionControls() { $doc = new XmlDocument('2.1'); $doc->load(self::samplesDir() . 'custom/runtime/routeitem_itemsessioncontrols.xml'); // Q01. $q01 = $doc->getDocumentComponent()->getComponentByIdentifier('Q01'); $this->assertInstanceOf('qtism\\data\\AssessmentItemRef', $q01); $this->assertEquals(2, $q01->getItemSessionControl()->getMaxAttempts()); // P02. $p02 = $doc->getDocumentComponent()->getComponentByIdentifier('P02'); $this->assertInstanceOf('qtism\\data\\TestPart', $p02); $this->assertEquals(4, $p02->getItemSessionControl()->getMaxAttempts()); }
/** * 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); } }
public function testBasicSelection() { $doc = new XmlDocument(); $doc->load(self::samplesDir() . 'custom/runtime/selection_and_ordering.xml'); $testPart = $doc->getDocumentComponent()->getComponentByIdentifier('testPart'); $this->assertEquals('testPart', $testPart->getIdentifier()); $s01 = $doc->getDocumentComponent()->getComponentByIdentifier('S01', true); $this->assertEquals('S01', $s01->getIdentifier()); // Prepare route selection of S01A. $s01a = $doc->getDocumentComponent()->getComponentByIdentifier('S01A', true); $this->assertEquals('S01A', $s01a->getIdentifier()); $s01aRoute = new SelectableRoute(); foreach ($s01a->getSectionParts() as $sectionPart) { $s01aRoute->addRouteItem($sectionPart, $s01a, $testPart, $doc->getDocumentComponent()); } // Prepare route selection of S01B. $s01b = $doc->getDocumentComponent()->getComponentByIdentifier('S01B', true); $this->assertEquals('S01B', $s01b->getIdentifier()); $s01bRoute = new SelectableRoute(); foreach ($s01b->getSectionParts() as $sectionPart) { $s01bRoute->addRouteItem($sectionPart, $s01b, $testPart, $doc->getDocumentComponent()); } $selection = new BasicSelection($s01, new SelectableRouteCollection(array($s01aRoute, $s01bRoute))); $selectedRoutes = $selection->select(); $selectedRoute = new SelectableRoute(); foreach ($selectedRoutes as $r) { $selectedRoute->appendRoute($r); } $routeCheck1 = self::isRouteCorrect($selectedRoute, array('Q1', 'Q2', 'Q3')); $routeCheck2 = self::isRouteCorrect($selectedRoute, array('Q4', 'Q5', 'Q6')); $this->assertFalse($routeCheck1 === true && $routeCheck2 === true); $this->assertTrue($routeCheck1 === true || $routeCheck2 === true); }
public function testLoadInteractionMixSaschsen() { $xmlDoc = new XmlDocument('2.1'); $xmlDoc->load(self::samplesDir() . 'ims/tests/interaction_mix_sachsen/interaction_mix_sachsen.xml'); $phpDoc = new PhpDocument(); $phpDoc->setDocumentComponent($xmlDoc->getDocumentComponent()); $file = tempnam('/tmp', 'qsm'); $phpDoc->save($file); $phpDoc = new PhpDocument(); $phpDoc->load($file); $this->assertEquals('InteractionMixSachsen_1901710679', $phpDoc->getDocumentComponent()->getIdentifier()); unlink($file); $this->assertFalse(file_exists($file)); }
/** * @depends testLoadAndResolveXIncludeSameBase */ public function testLoadAndResolveXIncludeDifferentBase() { $doc = new XmlDocument(); $doc->load(self::samplesDir() . 'custom/items/xinclude/xinclude_ns_in_tag_subfolder.xml', true); $doc->xInclude(); $includes = $doc->getDocumentComponent()->getComponentsByClassName('include'); $this->assertEquals(0, count($includes)); // And we should find an img component then! $imgs = $doc->getDocumentComponent()->getComponentsByClassName('img'); $this->assertEquals(1, count($imgs)); // Check that xml:base was appropriately resolved. In this case, // no content for xml:base because 'xinclude_ns_in_tag_content1.xml' is in the // same directory as the main xml file. $this->assertEquals('subfolder/', $imgs[0]->getXmlBase()); }
public function testModerateXmlBase() { $doc = new XmlDocument(); $doc->load(self::samplesDir() . 'rendering/xmlbase_2.xml'); $div = $doc->getDocumentComponent(); $this->assertInstanceOf('qtism\\data\\content\\xhtml\\text\\Div', $div); $this->assertFalse($div->hasXmlBase()); $this->assertEquals('', $div->getXmlBase()); $subDivs = $div->getComponentsByClassName('div'); $this->assertEquals(2, count($subDivs)); $this->assertTrue($subDivs[0]->hasXmlBase()); $this->assertEquals('http://www.qtism-project.org/farm/', $subDivs[0]->getXmlBase()); $this->assertTrue($subDivs[1]->hasXmlBase()); $this->assertEquals('http://www.qtism-project.org/birds/', $subDivs[1]->getXmlBase()); }
protected function convertToAssessmentItem(array $data) { list($xml, $manifest) = Converter::convertLearnosityToQtiItem($data); // Assert the XML string is formed and not empty // Also, assert manifest is in form of array, regardless it was empty or not $this->assertTrue(is_string($xml) && !empty($xml)); $this->assertTrue(is_array($manifest)); $document = new XmlDocument(); $document->loadFromString($xml); /** @var AssessmentItem $assessmentItem */ $assessmentItem = $document->getDocumentComponent(); // Basic assert on <assessmentItem> object $this->assertNotNull($assessmentItem); $this->assertTrue($assessmentItem instanceof AssessmentItem); return $assessmentItem; }
public function parse($xmlString, $validate = true) { // TODO: Remove this, and move it higher up LogService::flush(); $xmlDocument = new XmlDocument(); if ($validate === false) { LogService::log('QTI pre-validation is turned off, some invalid attributes might be stripped from XML content upon conversion'); } $xmlDocument->loadFromString($xmlString, $validate); /** @var AssessmentItem $assessmentItem */ $assessmentItem = $xmlDocument->getDocumentComponent(); if (!$assessmentItem instanceof AssessmentItem) { throw new MappingException('XML is not a valid <assessmentItem> document'); } return $this->parseWithAssessmentItemComponent($assessmentItem); }
/** * @dataProvider sharedStimulusFilenameProvider */ public function testIsValidSharedStimulus($filename, $response, $exception) { try { $xmlDocumentValid = SharedStimulusImporter::isValidSharedStimulus($filename); $this->assertTrue($response, __('It should not be valid')); $xmlDocument = new XmlDocument(); $xmlDocument->load($filename); $this->assertEquals($xmlDocument->getDomDocument()->C14N(), $xmlDocumentValid->getDomDocument()->C14N(), __('The loaded cml is wrong')); } catch (\Exception $e) { $this->assertFalse($response, __('It should not throw an exception')); if (!is_null($e)) { $this->assertInstanceOf(get_class($exception), $e, __('The exception class is wrong')); if ($exception->getMessage() !== '') { $this->assertEquals($exception->getMessage(), $e->getMessage(), __('The exception message is wrong')); } } } }
public function convert(item $item, array $questions) { // Make sure we clean up the log LogService::flush(); // Try to build the identifier using item `reference` // Otherwise, generate an alternative identifier and store the original reference as `label` $itemReference = $item->get_reference(); $itemIdentifier = Format::isIdentifier($itemReference, false) ? $itemReference : 'ITEM_' . StringUtil::generateRandomString(12); if ($itemReference !== $itemIdentifier) { LogService::log("The item `reference` ({$itemReference}) is not a valid identifier, thus can not be used for `assessmentItem` identifier. " . "Replaced it with randomly generated `{$itemIdentifier}` and stored the original `reference` as `label` attribute"); } $builder = new AssessmentItemBuilder(); $assessmentItem = $builder->build($itemIdentifier, $itemReference, $questions, $item->get_content()); $xml = new XmlDocument(); $xml->setDocumentComponent($assessmentItem); // Flush out all the error messages stored in this static class, also ensure they are unique $messages = array_values(array_unique(LogService::flush())); return [$xml->saveToString(true), $messages]; }
function testAssessmentTests(array $files, $validate = false) { $loaded = 0; $totalSpent = 0; foreach ($files as $f) { $start = microtime(); $testDoc = new XmlDocument(); $testDoc->load($f, $validate); $end = microtime(); $spent = spentTime($start, $end); $totalSpent += $spent; output("Test '" . pathinfo($f, PATHINFO_BASENAME) . "' loaded in " . sprintf("%.8f", $spent) . " seconds."); $partCount = count($testDoc->getDocumentComponent()->getComponentsByClassName('testPart')); $sectionCount = count($testDoc->getDocumentComponent()->getComponentsByClassName('assessmentSection')); $itemCount = count($testDoc->getDocumentComponent()->getComponentsByClassName('assessmentItemRef')); outputDescription("{$partCount} testPart(s), {$sectionCount} assessmentSection(s), {$itemCount} assessmentItemRef(s)"); outputDescription("Memory usage is " . memory_get_usage() / pow(1024, 2) . " MB"); output(''); $loaded++; } outputAverage($totalSpent / $loaded); }
public function testWrite() { $uri = self::samplesDir() . 'custom/standalone_assessmentsection.xml'; $doc = new XmlDocument(); $doc->load($uri); $assessmentSection = $doc->getDocumentComponent(); // Write the file. $uri = tempnam('/tmp', 'qsm'); $doc->save($uri); $this->assertTrue(file_exists($uri)); // Reload it. $doc->load($uri); $this->assertInstanceOf('qtism\\data\\AssessmentSection', $doc->getDocumentComponent()); // Retest. $this->testLoad($doc->getDocumentComponent()); unlink($uri); }
/** * Converts an assoc array to a QtiComponent using reflection * * @param array $testArray the assoc array * @param \qtism\data\QtiComponent|null $parent for recursive usage only * @param boolean $attach if we want to attach the component to it's parent or return it * @return QtiComponent|void */ private function arrayToComponent(array $testArray, QtiComponent $parent = null, $attach = true) { if (isset($testArray['qti-type']) && !empty($testArray['qti-type'])) { $compName = $this->lookupClass($testArray['qti-type']); if (!empty($compName)) { $reflector = new ReflectionClass($compName); $component = $this->createInstance($reflector, $testArray); $properties = array(); foreach ($this->getProperties($reflector) as $property) { $properties[$property->getName()] = $property; } foreach ($testArray as $key => $value) { if (array_key_exists($key, $properties)) { $class = $this->getPropertyClass($component, $properties[$key]); if (is_array($value) && array_key_exists('qti-type', $value)) { $this->arrayToComponent($value, $component, true); } else { $assignableValue = $this->componentValue($value, $class); if (!is_null($assignableValue)) { $this->setValue($component, $properties[$key], $assignableValue); } } } } if ($attach) { if (is_null($parent)) { $this->doc->setDocumentComponent($component); } else { $parentReflector = new ReflectionClass($parent); foreach ($this->getProperties($parentReflector) as $property) { if ($property->getName() === $testArray['qti-type']) { $this->setValue($parent, $property, $component); break; } } } } return $component; } } }
<?php /** * I don't even understand how it is correctly parsed... * But it's safe! */ use qtism\data\storage\xml\XmlDocument; use qtism\runtime\rendering\markup\xhtml\XhtmlRenderingEngine; require_once dirname(__FILE__) . '/../../qtism/qtism.php'; $doc = new XmlDocument(); $doc->load('../samples/rendering/php_highjacking_3.xml', true); $renderer = new XhtmlRenderingEngine(); $rendering = $renderer->render($doc->getDocumentComponent()); $rendering->formatOutput = true; echo $rendering->saveXML();
<?php use qtism\data\storage\xml\XmlDocument; use qtism\runtime\rendering\markup\xhtml\XhtmlRenderingEngine; require_once dirname(__FILE__) . '/../../qtism/qtism.php'; /* * The goal of this script is to demonstrate that empty <qti:object> elements * will be rendered as a non self-closing tag for browser compatibility. */ $doc = new XmlDocument(); $doc->load('../samples/rendering/empty_object.xml'); $renderer = new XhtmlRenderingEngine(); $rendering = $renderer->render($doc->getDocumentComponent()); $rendering->formatOutput = true; echo $rendering->saveXML();
<?php use qtism\runtime\rendering\markup\AbstractMarkupRenderingEngine; use qtism\data\storage\xml\XmlDocument; use qtism\runtime\rendering\markup\xhtml\XhtmlRenderingEngine; require_once dirname(__FILE__) . '/../../vendor/autoload.php'; $doc = new XmlDocument(); $doc->load(dirname(__FILE__) . '/../samples/rendering/xmlbase_1.xml'); $renderer = new XhtmlRenderingEngine(); if (empty($argv[1]) === false) { switch (strtolower($argv[1])) { case 'ignore': $renderer->setXmlBasePolicy(AbstractMarkupRenderingEngine::XMLBASE_IGNORE); break; case 'keep': $renderer->setXmlBasePolicy(AbstractMarkupRenderingEngine::XMLBASE_KEEP); break; case 'process': $renderer->setXmlBasePolicy(AbstractMarkupRenderingEngine::XMLBASE_PROCESS); break; } } if (empty($argv[2]) === false) { $renderer->setRootBase(strval($argv[2])); } $rendering = $renderer->render($doc->getDocumentComponent()); $rendering->formatOutput = true; echo $rendering->saveXML();
public function testWritePCIItem() { $doc = new XmlDocument(); $doc->load(self::samplesDir() . 'custom/interactions/custom_interaction_pci.xml'); $file = tempnam('/tmp', 'qsm'); $doc->save($file); $this->testLoadPCIItem($file); unlink($file); }
public function testCreateFormExploded(XmlCompactDocument $compactDoc = null) { $doc = new XmlDocument('2.1'); $file = self::samplesDir() . 'custom/interaction_mix_saschen_assessmentsectionref/interaction_mix_sachsen.xml'; $doc->load($file); $compactDoc = XmlCompactDocument::createFromXmlAssessmentTestDocument($doc, new LocalFileResolver()); $this->assertInstanceOf('qtism\\data\\storage\\xml\\XmlCompactDocument', $compactDoc); $this->assertEquals('InteractionMixSachsen_1901710679', $compactDoc->getDocumentComponent()->getIdentifier()); $this->assertEquals('Interaction Mix (Sachsen)', $compactDoc->getDocumentComponent()->getTitle()); $outcomeDeclarations = $compactDoc->getDocumentComponent()->getOutcomeDeclarations(); $this->assertEquals(2, count($outcomeDeclarations)); $this->assertEquals('SCORE', $outcomeDeclarations['SCORE']->getIdentifier()); $testParts = $compactDoc->getDocumentComponent()->getTestParts(); $this->assertEquals(1, count($testParts)); $this->assertEquals('testpartID', $testParts['testpartID']->getIdentifier()); $this->assertEquals(NavigationMode::NONLINEAR, $testParts['testpartID']->getNavigationMode()); $assessmentSections1stLvl = $testParts['testpartID']->getAssessmentSections(); $this->assertEquals(1, count($assessmentSections1stLvl)); $this->assertEquals('Container_45665458', $assessmentSections1stLvl['Container_45665458']->getIdentifier()); $assessmentSections2ndLvl = $assessmentSections1stLvl['Container_45665458']->getSectionParts(); $this->assertEquals(1, count($assessmentSections2ndLvl)); $this->assertInstanceOf('qtism\\data\\ExtendedAssessmentSection', $assessmentSections2ndLvl['Sektion_181865064']); $this->assertEquals(0, count($assessmentSections2ndLvl['Sektion_181865064']->getRubricBlockRefs())); $this->assertEquals('Sektion_181865064', $assessmentSections2ndLvl['Sektion_181865064']->getIdentifier()); $assessmentItemRefs = $assessmentSections2ndLvl['Sektion_181865064']->getSectionParts(); $this->assertEquals(13, count($assessmentItemRefs)); // Pick up 4 for a test... $assessmentItemRef = $assessmentItemRefs['Hotspot_278940407']; $this->assertInstanceOf('qtism\\data\\ExtendedAssessmentItemRef', $assessmentItemRef); $this->assertEquals('Hotspot_278940407', $assessmentItemRef->getIdentifier()); $responseDeclarations = $assessmentItemRef->getResponseDeclarations(); $this->assertEquals(1, count($responseDeclarations)); $this->assertEquals('RESPONSE', $responseDeclarations['RESPONSE']->getIdentifier()); $outcomeDeclarations = $assessmentItemRef->getOutcomeDeclarations(); $this->assertEquals(5, count($outcomeDeclarations)); $this->assertEquals('FEEDBACKBASIC', $outcomeDeclarations['FEEDBACKBASIC']->getIdentifier()); $file = tempnam('/tmp', 'qsm'); $compactDoc->save($file); $this->assertTrue(file_exists($file)); $compactDoc = new XmlCompactDocument('1.0'); $compactDoc->load($file); $compactDoc->schemaValidate(); unlink($file); $this->assertFalse(file_exists($file)); }
public function testCreateFromAssessmentTestEndAttemptIdentifiers() { $doc = new XmlDocument('2.1'); $file = self::samplesDir() . 'custom/test_contains_endattemptinteractions.xml'; $doc->load($file); $compactDoc = XmlCompactDocument::createFromXmlAssessmentTestDocument($doc, new LocalFileResolver()); // ExtendedAssessmentItemRefs! $assessmentItemRefs = $compactDoc->getDocumentComponent()->getComponentsByClassName('assessmentItemRef'); $this->assertEquals(2, count($assessmentItemRefs)); $assessmentItemRef = $assessmentItemRefs[0]; $endAttemptIdentifiers = $assessmentItemRef->getEndAttemptIdentifiers(); $this->assertEquals(1, count($endAttemptIdentifiers)); $this->assertEquals('HINT', $endAttemptIdentifiers[0]); $assessmentItemRef = $assessmentItemRefs[1]; $endAttemptIdentifiers = $assessmentItemRef->getEndAttemptIdentifiers(); $this->assertEquals(2, count($endAttemptIdentifiers)); $this->assertEquals('LOST', $endAttemptIdentifiers[0]); $this->assertEquals('LOST2', $endAttemptIdentifiers[1]); }
<?php use qtism\data\storage\xml\XmlDocument; use qtism\runtime\rendering\markup\xhtml\XhtmlRenderingEngine; require_once dirname(__FILE__) . '/../../qtism/qtism.php'; $doc = new XmlDocument(); $doc->load('../samples/rendering/selectpointinteraction_1.xml'); $renderer = new XhtmlRenderingEngine(); $rendering = $renderer->render($doc->getDocumentComponent()); $rendering->formatOutput = true; echo $rendering->saveXML();
<?php use qtism\data\storage\xml\XmlDocument; use qtism\runtime\rendering\markup\xhtml\XhtmlRenderingEngine; use qtism\data\storage\StorageException; require_once dirname(__FILE__) . '/../../vendor/autoload.php'; $doc = new XmlDocument(); try { $doc->load(dirname(__FILE__) . '/../samples/rendering/script_highjacking_2.xml'); } catch (StorageException $e) { do { echo $e->getMessage() . "\n"; $e = $e->getPrevious(); } while ($e); die; } $renderer = new XhtmlRenderingEngine(); $rendering = $renderer->render($doc->getDocumentComponent()); $rendering->formatOutput = true; echo $rendering->saveXML();
/** * Get the route (the way items are delivered into a test). * This method will compute the shuffling and other predefined conditions to take the test. * * @param string $testFilePath - the path of the QTI Test definition * @return array the test structure as it should be delivered. */ private function getRoute($testFilePath) { $route = array(); // Load the test definition. $testDefinition = new XmlDocument(); $testDefinition->load($testFilePath); // Make the test definition a compact one. Compact tests combine all needed // information to run a test instance. $resolver = new taoQtiTest_helpers_ItemResolver(); $compactTestDef = XmlCompactDocument::createFromXmlAssessmentTestDocument($testDefinition, $resolver); $sessionManager = new SessionManager(); $testSession = $sessionManager->createAssessmentTestSession($compactTestDef->getDocumentComponent()); $assessmentTest = $testSession->getAssessmentTest(); $renderingEngine = new XhtmlRenderingEngine(); $testPartId = null; $sectionId = null; //We are getting items with their respective test part and sections, so we need to restructure it foreach ($testSession->getRoute() as $routeItem) { $item = array('id' => $routeItem->getAssessmentItemRef()->getIdentifier(), 'href' => $routeItem->getAssessmentItemRef()->getHref()); $routeSections = $routeItem->getAssessmentSections()->getArrayCopy(); $lastSection = $routeSections[count($routeSections) - 1]; if ($sectionId != $lastSection->getIdentifier() || $testPartId != $routeItem->getTestPart()->getIdentifier()) { $sectionId = $lastSection->getIdentifier(); $rubricBlocks = array(); foreach ($routeItem->getAssessmentSections() as $section) { foreach ($section->getRubricBlocks() as $rubricBlock) { $xmlRendering = $renderingEngine->render($rubricBlock); $strRendering = $xmlRendering->saveXML($xmlRendering->documentElement); $finalRendering = ''; // No formatting at all :) ! foreach (preg_split('/\\n|\\r/u', $strRendering, -1, PREG_SPLIT_NO_EMPTY) as $line) { $finalRendering .= trim($line); } $rubricBlocks[] = $finalRendering; } } $section = array('id' => $section->getIdentifier(), 'title' => $section->getTitle(), 'rubricBlock' => $rubricBlocks, 'items' => array($item)); if ($testPartId != $routeItem->getTestPart()->getIdentifier()) { $testPartId = $routeItem->getTestPart()->getIdentifier(); $route[] = array('id' => $testPartId, 'sections' => array($section)); } else { $route = $this->addSectionToRoute($route, $testPartId, $section); } } else { $route = $this->addItemToRoute($route, $testPartId, $sectionId, $item); } } return array('id' => $assessmentTest->getIdentifier(), 'title' => $assessmentTest->getTitle(), 'testParts' => $route); }
public function testAppendNumberCorrectOutcomeProcessing() { $doc = new XmlDocument(); $doc->load(self::samplesDir() . 'categories.xml'); TestCategoryRulesUtils::appendNumberCorrectOutcomeProcessing($doc->getDocumentComponent(), 'math', 'MATH' . TestCategoryRulesUtils::NUMBER_CORRECT_SUFFIX); $this->assertInstanceOf('qtism\\data\\processing\\OutcomeProcessing', $doc->getDocumentComponent()->getOutcomeProcessing()); $outcomeRules = $doc->getDocumentComponent()->getOutcomeProcessing()->getOutcomeRules(); $this->assertCount(1, $outcomeRules); $this->assertInstanceOf('qtism\\data\\rules\\setOutcomeValue', $outcomeRules[0]); $this->assertEquals('MATH' . TestCategoryRulesUtils::NUMBER_CORRECT_SUFFIX, $outcomeRules[0]->getIdentifier()); $this->assertInstanceOF('qtism\\data\\expressions\\NumberCorrect', $outcomeRules[0]->getExpression()); $this->assertEquals(array('math'), $outcomeRules[0]->getExpression()->getIncludeCategories()->getArrayCopy()); // If a second call to TestCategoryRulesUtils::appendNumberCorrectOutcomeProcessing occurs for a variable wich // is already targeted by a setOutcomeValue rule, no new outcome rule should appear to avoid duplicates. TestCategoryRulesUtils::appendNumberCorrectOutcomeProcessing($doc->getDocumentComponent(), 'math', 'MATH' . TestCategoryRulesUtils::NUMBER_CORRECT_SUFFIX); $outcomeRules = $doc->getDocumentComponent()->getOutcomeProcessing()->getOutcomeRules(); $this->assertCount(1, $outcomeRules); }