public function testMarshall() { $identifier = 'myAssessmentTest'; $title = 'My Assessment Test'; $toolName = 'QTIStateMachine'; $toolVersion = '1.0b'; $assessmentSections = new AssessmentSectionCollection(); $assessmentSections[] = new AssessmentSection('myAssessmentSection', 'My Assessment Section', true); $testParts = new TestPartCollection(); $testParts[] = new TestPart('myTestPart', $assessmentSections); $div = new Div(); $div->setContent(new FlowCollection(array(new TextRun('Feedback!')))); $testFeedBacks = new TestFeedbackCollection(); $testFeedBacks[] = new TestFeedback('myFeedback', 'myOutcome', new FlowStaticCollection(array($div)), 'A Feedback'); $outcomeRules = new OutcomeRuleCollection(); $outcomeRules[] = new SetOutcomeValue('myOutcome', new BaseValue(BaseType::BOOLEAN, true)); $outcomeProcessing = new OutcomeProcessing($outcomeRules); $outcomeDeclarations = new OutcomeDeclarationCollection(); $outcomeDeclarations[] = new OutcomeDeclaration('myOutcome', BaseType::BOOLEAN); $component = new AssessmentTest($identifier, $title, $testParts); $component->setToolName($toolName); $component->setToolVersion($toolVersion); $component->setTestFeedbacks($testFeedBacks); $component->setOutcomeProcessing($outcomeProcessing); $component->setOutcomeDeclarations($outcomeDeclarations); $marshaller = $this->getMarshallerFactory('2.1.0')->createMarshaller($component); $element = $marshaller->marshall($component); $this->assertInstanceOf('\\DOMElement', $element); $this->assertEquals('assessmentTest', $element->nodeName); $this->assertEquals($identifier, $element->getAttribute('identifier')); $this->assertEquals($title, $element->getAttribute('title')); $this->assertEquals($toolName, $element->getAttribute('toolName')); $this->assertEquals($toolVersion, $element->getAttribute('toolVersion')); // testParts $this->assertEquals(1, $element->getElementsByTagName('testPart')->length); $this->assertTrue($element === $element->getElementsByTagName('testPart')->item(0)->parentNode); // assessmentSections $testPart = $element->getElementsByTagName('testPart')->item(0); $this->assertEquals(1, $element->getElementsByTagName('assessmentSection')->length); $this->assertTrue($testPart === $element->getElementsByTagName('assessmentSection')->item(0)->parentNode); // outcomeDeclarations $this->assertEquals(1, $element->getElementsByTagName('outcomeDeclaration')->length); $this->assertTrue($element === $element->getElementsByTagName('outcomeDeclaration')->item(0)->parentNode); // testFeedbacks $this->assertEquals(1, $element->getElementsByTagName('testFeedback')->length); $this->assertTrue($element === $element->getElementsByTagName('testFeedback')->item(0)->parentNode); // outcomeProcessing $this->assertEquals(1, $element->getElementsByTagName('outcomeProcessing')->length); $this->assertTrue($element === $element->getElementsByTagName('outcomeProcessing')->item(0)->parentNode); }
/** * Create a new instance of XmlCompactDocument from an XmlAssessmentTestDocument. * * @param XmlDocument $xmlAssessmentTestDocument An XmlAssessmentTestDocument object you want to store as a compact XML file. * @return XmlCompactDocument An XmlCompactAssessmentTestDocument object. * @throws XmlStorageException If an error occurs while transforming the XmlAssessmentTestDocument object into an XmlCompactAssessmentTestDocument object. */ public static function createFromXmlAssessmentTestDocument(XmlDocument $xmlAssessmentTestDocument, FileResolver $itemResolver = null) { $compactAssessmentTest = new XmlCompactDocument(); $identifier = $xmlAssessmentTestDocument->getDocumentComponent()->getIdentifier(); $title = $xmlAssessmentTestDocument->getDocumentComponent()->getTitle(); $assessmentTest = new AssessmentTest($identifier, $title); $assessmentTest->setOutcomeDeclarations($xmlAssessmentTestDocument->getDocumentComponent()->getOutcomeDeclarations()); $assessmentTest->setOutcomeProcessing($xmlAssessmentTestDocument->getDocumentComponent()->getOutcomeProcessing()); $assessmentTest->setTestFeedbacks($xmlAssessmentTestDocument->getDocumentComponent()->getTestFeedbacks()); $assessmentTest->setTestParts($xmlAssessmentTestDocument->getDocumentComponent()->getTestParts()); $assessmentTest->setTimeLimits($xmlAssessmentTestDocument->getDocumentComponent()->getTimeLimits()); $assessmentTest->setToolName($xmlAssessmentTestDocument->getDocumentComponent()->getToolName()); $assessmentTest->setToolVersion($xmlAssessmentTestDocument->getDocumentComponent()->getToolVersion()); // File resolution. $sectionResolver = new LocalFileResolver($xmlAssessmentTestDocument->getUrl()); if (is_null($itemResolver) === true) { $itemResolver = new LocalFileResolver($xmlAssessmentTestDocument->getUrl()); } else { $itemResolver->setBasePath($xmlAssessmentTestDocument->getUrl()); } // It simply consists of replacing assessmentItemRef and assessmentSectionRef elements. $trail = array(); // trailEntry[0] = a component, trailEntry[1] = from where we are coming (parent). $mark = array(); $root = $xmlAssessmentTestDocument->getDocumentComponent(); array_push($trail, array($root, $root)); while (count($trail > 0)) { $trailer = array_pop($trail); $component = $trailer[0]; $previous = $trailer[1]; if (!in_array($component, $mark) && count($component->getComponents()) > 0) { // First pass on a hierarchical node... go deeper in the n-ary tree. array_push($mark, $component); // We want to go back on this component. array_push($trail, $trailer); // Prepare further exploration. foreach ($component->getComponents()->getArrayCopy() as $comp) { array_push($trail, array($comp, $component)); } } else { if (in_array($component, $mark) || count($component->getComponents()) === 0) { // Second pass on a hierarchical node (we are bubbling up accross the n-ary tree) // OR // Leaf node if ($component instanceof AssessmentItemRef) { // Transform the ref in an compact extended ref. $compactRef = ExtendedAssessmentItemRef::createFromAssessmentItemRef($component); // find the old one and replace it. $previousParts = $previous->getSectionParts(); foreach ($previousParts as $k => $previousPart) { if ($previousParts[$k] === $component) { // If the previous processed component is an XmlAssessmentSectionDocument, // it means that the given baseUri must be adapted. $baseUri = $xmlAssessmentTestDocument->getUrl(); if ($component instanceof XmlDocument && $component->getDocumentComponent() instanceof AssessmentSection) { $baseUri = $component->getUrl(); } $itemResolver->setBasePath($baseUri); self::resolveAssessmentItemRef($compactRef, $itemResolver); $previousParts->replace($component, $compactRef); break; } } } else { if ($component instanceof AssessmentSectionRef) { // We follow the unreferenced AssessmentSection as if it was // the 1st pass. $assessmentSection = self::resolveAssessmentSectionRef($component, $sectionResolver); $previousParts = $previous->getSectionParts(); foreach ($previousParts as $k => $previousPart) { if ($previousParts[$k] === $component) { $previousParts->replace($component, $assessmentSection); break; } } array_push($trail, array($assessmentSection, $previous)); } else { if ($component instanceof AssessmentSection) { $assessmentSection = ExtendedAssessmentSection::createFromAssessmentSection($component); $previousParts = $previous instanceof TestPart ? $previous->getAssessmentSections() : $previous->getSectionParts(); foreach ($previousParts as $k => $previousPart) { if ($previousParts[$k] === $component) { $previousParts->replace($component, $assessmentSection); break; } } } else { if ($component === $root) { // 2nd pass on the root, we have to stop. $compactAssessmentTest->setDocumentComponent($assessmentTest); return $compactAssessmentTest; } } } } } } } }