private function buildTemplate(ItemBody $itemBody, array $interactionXmls)
 {
     // Build item's HTML content
     $content = QtiMarshallerUtil::marshallCollection($itemBody->getComponents());
     foreach ($interactionXmls as $interactionXml) {
         $content = str_replace($interactionXml, '{{response}}', $content);
     }
     return $content;
 }
 public function testMarshall()
 {
     $h1 = new H1();
     $h1->setContent(new InlineCollection(array(new TextRun('Super Item'))));
     $div = new Div();
     $div->setContent(new FlowCollection(array(new TextRun('This is some stimulus.'))));
     $itemBody = new ItemBody('my-body');
     $itemBody->setContent(new BlockCollection(array($h1, $div)));
     $element = $this->getMarshallerFactory()->createMarshaller($itemBody)->marshall($itemBody);
     $dom = new DOMDocument('1.0', 'UTF-8');
     $element = $dom->importNode($element, true);
     $this->assertEquals('<itemBody id="my-body"><h1>Super Item</h1><div>This is some stimulus.</div></itemBody>', $dom->saveXML($element));
 }
 public function map($itemReference, ItemBody $itemBody, QtiComponentCollection $interactionComponents, QtiComponentCollection $responseDeclarations = null, ResponseProcessingTemplate $responseProcessingTemplate = null)
 {
     $this->itemReference = $itemReference;
     $questionsXmls = [];
     $responseDeclarationsMap = [];
     if ($responseDeclarations) {
         /** @var ResponseDeclaration $responseDeclaration */
         foreach ($responseDeclarations as $responseDeclaration) {
             $responseDeclarationsMap[$responseDeclaration->getIdentifier()] = $responseDeclaration;
         }
     }
     foreach ($interactionComponents as $component) {
         /* @var $component Interaction */
         $questionReference = $this->itemReference . '_' . $component->getResponseIdentifier();
         // Process <responseDeclaration>
         $responseDeclaration = isset($responseDeclarationsMap[$component->getResponseIdentifier()]) ? $responseDeclarationsMap[$component->getResponseIdentifier()] : null;
         $mapper = $this->getMapperInstance($component->getQtiClassName(), [$component, $responseDeclaration, $responseProcessingTemplate]);
         $question = $mapper->getQuestionType();
         $this->questions[$questionReference] = new Question($question->get_type(), $questionReference, $question);
         $questionsXmls[$questionReference] = ['qtiClassName' => $component->getQtiClassName(), 'responseIdentifier' => $component->getResponseIdentifier()];
     }
     // Build item's HTML content
     $extraContentHtml = new SimpleHtmlDom();
     if (!$extraContentHtml->load(QtiMarshallerUtil::marshallCollection($itemBody->getComponents()), false)) {
         throw new \Exception('Issues with the content for itemBody, it might not be valid');
     }
     foreach ($questionsXmls as $questionReference => $interactionData) {
         // Append this question span to our `item` content as it is
         $this->content .= '<span class="learnosity-response question-' . $questionReference . '"></span>';
         // Clean up interaction HTML content
         $qtiClassName = $interactionData['qtiClassName'];
         $responseIdentifier = $interactionData['responseIdentifier'];
         $toFind = $qtiClassName . '[responseIdentifier="' . $responseIdentifier . '"]';
         foreach ($extraContentHtml->find($toFind) as &$tag) {
             $tag->outertext = '';
         }
     }
     $extraContent = $extraContentHtml->save();
     // Making assumption question always has stimulus `right`?
     // So, prepend the extra content on the stimulus on the first question
     if (!empty(trim($extraContent))) {
         $firstQuestionReference = key($this->questions);
         $newStimulus = $extraContent . $this->questions[$firstQuestionReference]->get_data()->get_stimulus();
         $this->questions[$firstQuestionReference]->get_data()->set_stimulus($newStimulus);
         LogService::log('Extra <itemBody> content is prepended to question stimulus and please verify as this `might` break item content structure');
     }
     return true;
 }
 public function processAssessmentItem(AssessmentItem $assessmentItem)
 {
     // TODO: Yea, we ignore rubric but what happen if the rubric is deep inside nested
     $newCollection = new BlockCollection();
     $itemBodyNew = new ItemBody();
     /** @var QtiComponent $component */
     foreach ($assessmentItem->getItemBody()->getContent() as $key => $component) {
         if (!$component instanceof RubricBlock) {
             $newCollection->attach($component);
         } else {
             LogService::log('Does not support <rubricBlock>. Ignoring <rubricBlock>');
         }
     }
     $itemBodyNew->setContent($newCollection);
     $assessmentItem->setItemBody($itemBodyNew);
     return $assessmentItem;
 }
 public static function buildItemBody(QtiComponentCollection $componentCollection)
 {
     $itemBody = new ItemBody('testItemBody');
     $blockCollection = new BlockCollection();
     $p = new P();
     $pCollection = new InlineCollection();
     $pCollection->attach(new TextRun('The Matrix movie is starring '));
     // Build the <itemBody>
     $blockCollection->attach($p);
     foreach ($componentCollection as $c) {
         if ($c instanceof InlineInteraction) {
             $pCollection->attach($c);
         } else {
             $blockCollection->attach($c);
         }
     }
     $p->setContent($pCollection);
     $itemBody->setContent($blockCollection);
     return $itemBody;
 }
 protected function buildAssessmentItem(array $interactions, $responseProcessingTemplate = '')
 {
     $assessmentItem = new AssessmentItem('testItemID', 'testItemTitle', false);
     $responseProcessing = new ResponseProcessing();
     $responseProcessing->setTemplate($responseProcessingTemplate);
     $assessmentItem->setResponseProcessing($responseProcessing);
     $itemBody = new ItemBody();
     $p = new P();
     $pCollection = new InlineCollection();
     $pCollection->attach(new TextRun('The Matrix movie is starring '));
     $pCollection->attach(new TextRun('.'));
     foreach ($interactions as $interaction) {
         $pCollection->attach($interaction);
     }
     $p->setContent($pCollection);
     $collection = new BlockCollection();
     $collection->attach($p);
     $itemBody->setContent($collection);
     $assessmentItem->setItemBody($itemBody);
     return $assessmentItem;
 }
 private function buildItemBodyWithSingleInteraction(TextEntryInteraction $interactionOne = null)
 {
     $interactionOne = empty($interactionOne) ? new TextEntryInteraction('testIdentifierOne') : $interactionOne;
     $itemBody = new ItemBody();
     $itemBodyCollection = new BlockCollection();
     // Build `<p>The Matrix .... <inlineChoiceInteraction...></inlineChoiceInteraction>.</p>`
     $p = new P();
     $pCollection = new InlineCollection();
     $pCollection->attach(new TextRun('The Matrix movie is starring '));
     $pCollection->attach($interactionOne);
     $pCollection->attach(new TextRun('.'));
     $p->setContent($pCollection);
     // Build the <itemBody>
     $itemBodyCollection->attach($p);
     $itemBody->setContent($itemBodyCollection);
     return $itemBody;
 }
 private function buildItemBodyWithTwoInteractions()
 {
     $interactionOne = InlineChoiceInteractionBuilder::buildSimple('testIdentifierOne', ['sydney' => 'Sydney', 'melbourne' => 'Melbourne', 'canberra' => 'Canberra']);
     $interactionTwo = InlineChoiceInteractionBuilder::buildSimple('testIdentifierTwo', ['hugh' => 'Hugh Jackman', 'keanu' => 'Keanu Reeves', 'gloria' => 'Gloria Foster']);
     $itemBody = new ItemBody();
     $itemBodyCollection = new BlockCollection();
     // Build `<p>The Matrix .... <inlineChoiceInteraction...></inlineChoiceInteraction>.</p>`
     $p = new P();
     $pCollection = new InlineCollection();
     $pCollection->attach(new TextRun('The Matrix movie is filmed at '));
     $pCollection->attach($interactionOne);
     $pCollection->attach(new TextRun(', and starring '));
     $pCollection->attach($interactionTwo);
     $p->setContent($pCollection);
     // Build the <itemBody>
     $itemBodyCollection->attach($p);
     $itemBody->setContent($itemBodyCollection);
     return $itemBody;
 }
 private function buildItemBodySimple(array $interactions)
 {
     $interactions = array_values($interactions);
     $contentCollection = new QtiComponentCollection();
     // Append the extra contents belong to an interaction before the interaction itself
     foreach ($interactions as $data) {
         if (isset($data['extraContent'])) {
             $content = QtiMarshallerUtil::unmarshallElement($data['extraContent']);
             $contentCollection->merge($content);
         }
         $contentCollection->attach($data['interaction']);
     }
     $itemBody = new ItemBody();
     $itemBody->setContent(ContentCollectionBuilder::buildBlockCollectionContent($contentCollection));
     return $itemBody;
 }