public function testClassSelection() { $doc = new XmlCompactDocument(); $doc->load(self::samplesDir() . 'custom/runtime/itemsubset.xml'); $iterator = new QtiComponentIterator($doc->getDocumentComponent(), array('responseProcessing')); $i = 0; foreach ($iterator as $responseProcessing) { $this->assertEquals($iterator->key(), 'responseProcessing'); $i++; } $this->assertEquals(7, $i); }
/** * Seek for the position of $component in the AssessmentTest tree. * * @param QtiComponent $component A QtiComponent object which is supposed to be in the AssessmentTest tree. * @return integer The position of $component in the AssessmentTest tree. * @throws OutOfBoundsException If no such $component could be found in the AssessmentTest tree. */ public function seekPosition(QtiComponent $component) { if (($position = $this->getPositionFromComponentStore($component)) !== false) { // Already explored. return $position; } // We have to find it! while ($this->iterator->valid() === true) { $current = $this->iterator->current(); $newPosition = $this->addToComponentStore($current); $this->iterator->next(); if ($current === $component) { return $newPosition; } } $class = $component->getQtiClassName(); $msg = "Unable to find the position of a QtiComponent with QTI class '{$class}'."; throw new OutOfBoundsException($msg); }
public function beforeSave(QtiComponent $documentComponent, $uri) { // Take care of rubricBlock explosion. Transform // actual rubricBlocks in rubricBlockRefs. if ($this->mustExplodeRubricBlocks() === true) { // Get all rubricBlock elements... $iterator = new QtiComponentIterator($documentComponent, array('rubricBlock')); $sectionCount = new SplObjectStorage(); foreach ($iterator as $rubricBlock) { // $section contains the assessmentSection the rubricBlock is related to. $section = $iterator->parent(); // determine the occurence number of the rubricBlock relative to its section. if (isset($sectionCount[$section]) === false) { $sectionCount[$section] = 0; } $sectionCount[$section] = $sectionCount[$section] + 1; $occurence = $sectionCount[$section]; // determine a suitable file name for the external rubricBlock definition. $rubricBlockRefId = 'RB_' . $section->getIdentifier() . '_' . $occurence; $href = './rubricBlock_' . $rubricBlockRefId . '.xml'; $doc = new XmlDocument(); $doc->setDocumentComponent($rubricBlock); try { $pathinfo = pathinfo($uri); $doc->save($pathinfo['dirname'] . DIRECTORY_SEPARATOR . $href); // replace the rubric block with a reference. $sectionRubricBlocks = $section->getRubricBlocks(); $sectionRubricBlocks->remove($rubricBlock); $sectionRubricBlockRefs = $section->getRubricBlockRefs(); $sectionRubricBlockRefs[] = new RubricBlockRef($rubricBlockRefId, $href); } catch (XmlStorageException $e) { $msg = "An error occured while creating external rubrickBlock definition(s)."; throw new XmlStorageException($msg, $e); } } } }
/** * @see \qtism\data\storage\xml\XmlDocument::beforeSave() */ public function beforeSave(QtiComponent $documentComponent, $uri) { // Take care of rubricBlock explosion. Transform actual rubricBlocks in rubricBlockRefs. if ($this->mustExplodeRubricBlocks() === true) { // Get all rubricBlock elements... $iterator = new QtiComponentIterator($documentComponent, array('rubricBlock')); $sectionCount = new SplObjectStorage(); foreach ($iterator as $rubricBlock) { // $section contains the assessmentSection the rubricBlock is related to. $section = $iterator->parent(); // determine the occurence number of the rubricBlock relative to its section. if (isset($sectionCount[$section]) === false) { $sectionCount[$section] = 0; } $sectionCount[$section] = $sectionCount[$section] + 1; $occurence = $sectionCount[$section]; // determine a suitable file name for the external rubricBlock definition. $rubricBlockRefId = 'RB_' . $section->getIdentifier() . '_' . $occurence; $href = './rubricBlock_' . $rubricBlockRefId . '.xml'; $doc = new XmlDocument(); $doc->setDocumentComponent($rubricBlock); try { $pathinfo = pathinfo($uri); $doc->save($pathinfo['dirname'] . DIRECTORY_SEPARATOR . $href); // replace the rubric block with a reference. $sectionRubricBlocks = $section->getRubricBlocks(); $sectionRubricBlocks->remove($rubricBlock); $sectionRubricBlockRefs = $section->getRubricBlockRefs(); $sectionRubricBlockRefs[] = new RubricBlockRef($rubricBlockRefId, $href); } catch (XmlStorageException $e) { $msg = "An error occured while creating external rubrickBlock definition(s)."; throw new XmlStorageException($msg, XmlStorageException::UNKNOWN, $e); } } } // Take care of testFeedback explosion. Transform actual testFeedbacks in testFeedbackRefs. if ($this->mustExplodeTestFeedbacks() === true) { $iterator = new QtiComponentIterator($documentComponent, array('testFeedback')); $testPartCount = new SplObjectStorage(); $testCount = 0; foreach ($iterator as $testFeedback) { $parent = $iterator->parent(); if ($parent instanceof TestPart) { if (isset($testPartCount[$parent]) === false) { $testPartCount[$parent] = 0; } $testPartCount[$parent] = $testPartCount[$parent] + 1; $occurence = $testPartCount[$parent]; } else { // It's a testFeedback related to an assessmentTest. $testCount += 1; $occurence = $testCount; } $parentId = $parent->getIdentifier(); $href = "./testFeedback_TF_{$parentId}_{$occurence}.xml"; // Generate the document. $doc = new XmlDocument(); $doc->setDocumentComponent($testFeedback); try { $pathinfo = pathinfo($uri); $doc->save($pathinfo['dirname'] . DIRECTORY_SEPARATOR . $href); $parent->getTestFeedbacks()->remove($testFeedback); $testFeedbackRefs = $parent->getTestFeedbackRefs(); $testFeedbackRefs[] = new TestFeedbackRef($testFeedback->getIdentifier(), $testFeedback->getOutcomeIdentifier(), $testFeedback->getAccess(), $testFeedback->getShowHide(), $href); } catch (XmlStorageException $e) { $msg = "An error occured while creating external testFeedback definition(s)."; throw new XmlStorageException($msg, XmlStorageException::UNKNOWN, $e); } } } }
/** * Resolve include components. * * After the item has been loaded using the load or loadFromString method, * the include components can be resolved by calling this method. Files will * be included following the rules described by the XInclude specification. * * @param boolean $validate Whether or not validate files being included. * @throws \LogicException If the method is called prior the load or loadFromString method was called. * @throws \qtism\data\storage\xml\XmlStorageException If an error occured while parsing or validating files to be included. */ public function xInclude($validate = false) { if (($root = $this->getDocumentComponent()) !== false) { $baseUri = str_replace('\\', '/', $this->getDomDocument()->documentElement->baseURI); $pathinfo = pathinfo($baseUri); $basePath = $pathinfo['dirname']; $iterator = new QtiComponentIterator($root, array('include')); foreach ($iterator as $include) { $parent = $iterator->parent(); // Is the parent something we can deal with for replacement? $reflection = new ReflectionClass($parent); if ($reflection->hasMethod('getContent') === true && $parent->getContent() instanceof QtiComponentCollection) { $href = $include->getHref(); if (Url::isRelative($href) === true) { $href = Url::rtrim($basePath) . '/' . Url::ltrim($href); $doc = new XmlDocument(); $doc->load($href, $validate); $includeRoot = $doc->getDocumentComponent(); if ($includeRoot instanceof Flow) { // Derive xml:base... $xmlBase = Url::ltrim(str_replace($basePath, '', $href)); $xmlBasePathInfo = pathinfo($xmlBase); if ($xmlBasePathInfo['dirname'] !== '.') { $includeRoot->setXmlBase($xmlBasePathInfo['dirname'] . '/'); } } $parent->getContent()->replace($include, $includeRoot); } } } } else { $msg = "Cannot include fragments prior to loading any file."; throw new LogicException($msg); } }