Пример #1
0
 public function convert(BaseQuestionType $questionType, $interactionIdentifier, $interactionLabel)
 {
     /** @var clozetext $question */
     $question = $questionType;
     // Extra text that can't be mapped since we are in textEntryInteraction which does not have prompt
     $this->extraContent = $question->get_stimulus();
     // Replace {{ response }} with `textEntryInteraction` elements
     $maxLength = !is_null($question->get_max_length()) ? intval($question->get_max_length()) : 15;
     // Set default to `15` if not set
     $index = 0;
     $template = preg_replace_callback('/{{response}}/', function ($match) use(&$index, $interactionIdentifier, $interactionLabel, $maxLength) {
         $interaction = new TextEntryInteraction($interactionIdentifier . '_' . $index);
         $interaction->setLabel($interactionLabel);
         $interaction->setExpectedLength($maxLength);
         $index++;
         $replacement = QtiMarshallerUtil::marshall($interaction);
         return $replacement;
     }, $question->get_template());
     // Wrap this interaction in a block since our `clozetext` `template` meant to be blocky and not inline
     $div = new Div();
     $div->setClass('lrn-template');
     $div->setContent(ContentCollectionBuilder::buildFlowCollectionContent(QtiMarshallerUtil::unmarshallElement($template)));
     // Build validation
     $isCaseSensitive = is_null($question->get_case_sensitive()) ? true : $question->get_case_sensitive();
     $validationBuilder = new ClozetextValidationBuilder($isCaseSensitive);
     list($responseDeclaration, $responseProcessing) = $validationBuilder->buildValidation($interactionIdentifier, $question->get_validation(), $isCaseSensitive);
     return [$div, $responseDeclaration, $responseProcessing];
 }
Пример #2
0
 public function buildItemBody(array $interactions, $content = '')
 {
     // Try to build the <itemBody> according to items` content if exists
     if (empty($content)) {
         return $this->buildItemBodySimple($interactions);
     }
     try {
         return $this->buildItemBodyWithItemContent($interactions, $content);
         // If anything fails, <itemBody> can't be mapped due to whatever reasons
         // Probably simply due to its being wrapped in a tag which only accept inline content
         // Simply build it without considering items` content and put the content on the top
     } catch (\Exception $e) {
         $itemBody = $this->buildItemBodySimple($interactions);
         $itemBodyContent = new BlockCollection();
         // Build the div bundle that contains all the item`s content
         // minus those questions and features `span`
         $html = new SimpleHtmlDom();
         $html->load($content);
         foreach ($html->find('span.learnosity-response') as &$span) {
             $span->outertext = '';
         }
         $div = new Div();
         $contentCollection = QtiMarshallerUtil::unmarshallElement($html->save());
         $div->setContent(ContentCollectionBuilder::buildFlowCollectionContent($contentCollection));
         $itemBodyContent->attach($div);
         $itemBodyContent->merge($itemBody->getComponents());
         $itemBody->setContent($itemBodyContent);
         LogService::log('Interactions are failed to be mapped with `item` content: ' . $e->getMessage() . '. Thus, interactions are separated from its actual `item` content and appended in the bottom');
         return $itemBody;
     }
 }
 protected function marshallChildrenKnown(QtiComponent $component, array $elements)
 {
     /** @var Object $component */
     switch ($this->getMIMEType($component->getType())) {
         case self::MIME_IMAGE:
             $this->checkObjectComponents($component, '<img> tag');
             $element = self::getDOMCradle()->createElement('img');
             $element->setAttribute('src', $component->getData());
             return $element;
             break;
         case self::MIME_AUDIO:
             $this->checkObjectComponents($component, '`audioplayer` feature');
             $element = self::getDOMCradle()->createElement('span');
             $element->setAttribute('class', 'learnosity-feature');
             $element->setAttribute('data-type', 'audioplayer');
             $element->setAttribute('data-src', $component->getData());
             return $element;
             break;
         case self::MIME_VIDEO:
             $this->checkObjectComponents($component, '`videoplayer` feature');
             $element = self::getDOMCradle()->createElement('span');
             $element->setAttribute('class', 'learnosity-feature');
             $element->setAttribute('data-type', 'videoplayer');
             $element->setAttribute('data-src', $component->getData());
             return $element;
             break;
         case self::MIME_HTML:
             $fragment = self::getDOMCradle()->createDocumentFragment();
             $fragment->appendXML(QtiMarshallerUtil::marshallCollection(ContentCollectionBuilder::buildFlowCollectionContent($component->getComponents())));
             $element = self::getDOMCradle()->createElement('div');
             $element->setAttribute('data-type', 'sharedpassage');
             $element->appendChild($fragment);
             return $element;
             break;
         default:
             // TODO: Need to think external HTML object file, what we are going to do with them?
             // Just parse <object> as default
             LogService::log('Unknown <object> MIME type, outputting <object> as it is');
             return parent::marshallChildrenKnown($component, $elements);
     }
 }
 public function convert(BaseQuestionType $questionType, $interactionIdentifier, $interactionLabel)
 {
     /** @var clozedropdown $question */
     $question = $questionType;
     // Extra text that can't be mapped since we are in textEntryInteraction which does not have prompt
     $this->extraContent = $question->get_stimulus();
     // Replace {{ response }} with `textEntryInteraction` elements
     $valueIdentifierMapPerInlineChoices = [];
     $index = 0;
     $possibleResponses = $question->get_possible_responses();
     $template = preg_replace_callback('/{{response}}/', function ($match) use(&$index, &$valueIdentifierMapPerInlineChoices, $possibleResponses, $interactionIdentifier, $interactionLabel) {
         $inlineChoiceCollection = new InlineChoiceCollection();
         if (!isset($possibleResponses[$index])) {
             throw new MappingException('Invalid `possible_responses`, missing entries');
         }
         foreach ($possibleResponses[$index] as $choiceIndex => $choiceValue) {
             $inlineChoiceIdentifier = 'INLINECHOICE_' . $choiceIndex;
             $valueIdentifierMapPerInlineChoices[$index][$choiceValue] = $inlineChoiceIdentifier;
             // Update this map so can be used later upon building responseDeclaration objects
             $inlineChoice = new InlineChoice($inlineChoiceIdentifier);
             $inlineChoiceContent = new TextOrVariableCollection();
             $inlineChoiceContent->attach(new TextRun($choiceValue));
             $inlineChoice->setContent($inlineChoiceContent);
             $inlineChoiceCollection->attach($inlineChoice);
         }
         $interaction = new InlineChoiceInteraction($interactionIdentifier . '_' . $index, $inlineChoiceCollection);
         $interaction->setLabel($interactionLabel);
         $index++;
         $replacement = QtiMarshallerUtil::marshall($interaction);
         return $replacement;
     }, $question->get_template());
     // Wrap this interaction in a block since our `clozedropdown` `template` meant to be blocky and not inline
     $div = new Div();
     $div->setClass('lrn-template');
     $div->setContent(ContentCollectionBuilder::buildFlowCollectionContent(QtiMarshallerUtil::unmarshallElement($template)));
     // Build validation
     $validationBuilder = new ClozedropdownValidationBuilder($valueIdentifierMapPerInlineChoices);
     list($responseDeclaration, $responseProcessing) = $validationBuilder->buildValidation($interactionIdentifier, $question->get_validation());
     return [$div, $responseDeclaration, $responseProcessing];
 }