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 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;
 }