Esempio n. 1
0
 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];
 }
 /**
  * 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;
         }
     }
 }
 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);
             }
         }
     }
 }
 /**
  * Explode the rubric blocks of the test definition into separate QTI-XML files and
  * remove the compact XML document from the file system (useless for
  * the rest of the compilation process).
  * 
  * @param XmlCompactDocument $compiledDoc
  */
 protected function explodeRubricBlocks(XmlCompactDocument $compiledDoc)
 {
     $privateDir = $this->getPrivateDirectory();
     $explodedRubricBlocks = $compiledDoc->explodeRubricBlocks();
     foreach ($explodedRubricBlocks as $href => $rubricBlock) {
         $doc = new XmlDocument();
         $doc->setDocumentComponent($rubricBlock);
         $data = $doc->saveToString();
         $privateDir->write($href, $data);
     }
 }
Esempio n. 5
0
 /**
  * @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);
             }
         }
     }
 }