public function build($itemIdentifier, $itemLabel, array $questions, $content = '')
 {
     // Initialise our <assessmentItem>
     $assessmentItem = new AssessmentItem($itemIdentifier, $itemIdentifier, false);
     $assessmentItem->setLabel($itemLabel);
     $assessmentItem->setOutcomeDeclarations($this->buildOutcomeDeclarations());
     $assessmentItem->setToolName('Learnosity');
     // Store interactions on this array to later be placed on <itemBody>
     $interactions = [];
     $responseDeclarationCollection = new ResponseDeclarationCollection();
     $responseProcessingTemplates = [];
     foreach ($questions as $question) {
         /** @var Question $question */
         // Map the `questions` and its validation objects to be placed at <itemBody>
         // The extraContent usually comes from `stimulus` of item that mapped to inline interaction and has no `prompt`
         list($interaction, $responseDeclaration, $responseProcessing, $extraContent) = $this->map($question);
         if (!empty($responseDeclaration)) {
             // TODO: Need to tidy this up
             // Well sometimes we can have multiple response declarations, ie. clozetext
             if ($responseDeclaration instanceof ResponseDeclarationCollection) {
                 $responseDeclarationCollection->merge($responseDeclaration);
             } else {
                 $responseDeclarationCollection->attach($responseDeclaration);
             }
         }
         if (!empty($responseProcessing)) {
             /** @var ResponseProcessing $responseProcessing */
             $responseProcessingTemplates[] = $responseProcessing->getTemplate();
         }
         $interactions[$question->get_reference()]['interaction'] = $interaction;
         if (!empty($extraContent)) {
             $interactions[$question->get_reference()]['extraContent'] = $extraContent;
         }
     }
     // Build <itemBody>
     $assessmentItem->setItemBody($this->itemBodyBuilder->buildItemBody($interactions, $content));
     // Map <responseDeclaration>
     if (!empty($responseDeclarationCollection)) {
         $assessmentItem->setResponseDeclarations($responseDeclarationCollection);
     }
     // Map <responseProcessing> - combine response processing from questions
     // TODO: Tidy up this stuff
     if (!empty($responseProcessingTemplates)) {
         $templates = array_unique($responseProcessingTemplates);
         $isOnlyMatchCorrect = count($templates) === 1 && $templates[0] === Constants::RESPONSE_PROCESSING_TEMPLATE_MATCH_CORRECT;
         $responseProcessing = new ResponseProcessing();
         $responseProcessing->setTemplate($isOnlyMatchCorrect ? Constants::RESPONSE_PROCESSING_TEMPLATE_MATCH_CORRECT : Constants::RESPONSE_PROCESSING_TEMPLATE_MAP_RESPONSE);
         $assessmentItem->setResponseProcessing($responseProcessing);
     }
     return $assessmentItem;
 }
 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 function processAssessmentItem(AssessmentItem $assessmentItem)
 {
     $itemBody = $assessmentItem->getItemBody();
     foreach ($itemBody->getIterator() as $component) {
         if ($component instanceof Math) {
             $element = $component->getXml()->documentElement;
             // Remove prefix if exists for conversion
             // ie. <m:math> to just <math>
             $element->removeAttributeNS($element->namespaceURI, $element->prefix);
             $component->setXmlString($element->ownerDocument->saveXML());
             // Remove MathML namespace declaration
             $component->setTargetNamespace('');
             $this->hasMathML = true;
         }
     }
     $assessmentItem->setItemBody($itemBody);
     return $assessmentItem;
 }
 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;
 }