protected function buildComponentCollectionWithNonMergeableInteractionTypes() { $collection = new QtiComponentCollection(); $choiceInteraction = ChoiceInteractionBuilder::buildSimple('testChoiceInteractionIdentifier', ['ChoiceOne' => 'A', 'ChoiceTwo' => 'B']); $collection->attach($choiceInteraction); return $collection; }
protected function buildResponseDeclaration() { $responseDeclartation = ResponseDeclarationBuilder::buildWithCorrectResponse('testChoiceInteractionIdentifier', ['1', '2']); $collection = new QtiComponentCollection(); $collection->attach($responseDeclartation); return $collection; }
public static function unmarshallElement($string) { try { libxml_use_internal_errors(true); $dom = new DOMDocument('1.0', 'UTF-8'); $dom->formatOutput = true; // TODO: Try to clean as much as I can blah $string = html_entity_decode($string, ENT_XHTML); // TODO: Can only unmarshall nice stuff, doesnt work with dodgy or invalid HTML if (!$dom->loadXML("<body>{$string}</body>", LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD)) { $errors = libxml_get_errors(); throw new \Exception('Something wrong with XML format'); } $marshallerFactory = new LearnosityMarshallerFactory(); $components = new QtiComponentCollection(); foreach ($dom->documentElement->childNodes as $element) { if ($element instanceof \DOMText) { $component = new TextRun($element->nodeValue); } else { $marshaller = $marshallerFactory->createMarshaller($element); $component = $marshaller->unmarshall($element); } $components->attach($component); } return $components; } catch (\Exception $e) { throw new MappingException('[Unable to transform to QTI] ' . $e->getMessage()); } }
private function buildTemplate(QtiGapMatchInteraction $interaction) { $templateCollection = new QtiComponentCollection(); foreach ($interaction->getComponents() as $component) { // Ignore `prompt` and the `gapChoice` since they are going to be mapped somewhere else :) if (!$component instanceof Prompt && !$component instanceof GapChoice) { $templateCollection->attach($component); } } $gapIdentifiers = []; $content = QtiMarshallerUtil::marshallCollection($templateCollection); foreach ($interaction->getComponentsByClassName('gap', true) as $gap) { /** @var Gap $gap */ $gapIdentifiers[] = $gap->getIdentifier(); $gapString = QtiMarshallerUtil::marshall($gap); $content = str_replace($gapString, '{{response}}', $content); } return [$content, $gapIdentifiers]; }
private function buildTemplate(HottextInteraction $interaction) { $templateCollection = new QtiComponentCollection(); foreach ($interaction->getComponents() as $component) { // Ignore `prompt` since its going to be mapped to `stimulus` if (!$component instanceof Prompt) { $templateCollection->attach($component); } } $content = QtiMarshallerUtil::marshallCollection($templateCollection); foreach ($interaction->getComponentsByClassName('hottext') as $hottext) { /** @var Hottext $hottext */ $hottextString = QtiMarshallerUtil::marshall($hottext); $tokenSpan = new span(); $tokenSpan->setClass('lrn_token'); $inlineCollection = new InlineCollection(); foreach ($hottext->getComponents() as $c) { $inlineCollection->attach($c); } $tokenSpan->setContent($inlineCollection); $content = str_replace($hottextString, QtiMarshallerUtil::marshall($tokenSpan), $content); } return $content; }
private static function validateContent($content) { if (!$content instanceof QtiComponent && !$content instanceof QtiComponentCollection) { throw new \InvalidArgumentException('Expected `QtiComponent` or `QtiComponentCollection`'); } if ($content instanceof QtiComponent) { $collection = new QtiComponentCollection(); $collection->attach($content); $content = $collection; } return $content; }
public function testInvalidResponseProcessingTemplate() { $itemBody = $this->buildItemBodyWithSingleInteraction(); $responseDeclarations = new QtiComponentCollection(); $responseDeclarations->attach(ResponseDeclarationBuilder::buildWithMapping('testIdentifierOne', ['Sydney' => [2, false], 'sydney' => [1, false]])); $mapper = new MergedTextEntryInteractionMapper('dummyReference', $itemBody, $responseDeclarations, ResponseProcessingTemplate::getFromTemplateUrl('')); $question = $mapper->getQuestionType(); $this->assertNotNull($question); $this->assertNull($question->get_validation()); $this->assertCount(1, LogService::read()); }
public function testSingleInteractionWithMapResponseValidation() { $itemBody = $this->buildItemBodyWithSingleInteraction(); $responseDeclarations = new QtiComponentCollection(); $responseDeclarations->attach(ResponseDeclarationBuilder::buildWithMapping('testIdentifierOne', ['canberra' => [0.5, false], 'sydney' => [2, false]])); $mapper = new MergedInlineChoiceInteractionMapper('dummyQuestionReference', $itemBody, $responseDeclarations, ResponseProcessingTemplate::mapResponse()); $question = $mapper->getQuestionType(); // Should map question correctly with `validation` object of `exactMatch` scoring type $this->assertNotNull($question); $this->assertEquals('<p>The Matrix movie is filmed at {{response}}. Boo!</p>', $question->get_template()); $this->assertEquals('clozedropdown', $question->get_type()); // Should set both `valid_response` and `alt_responses` for multiple correct values $validation = $question->get_validation(); $this->assertNotNull($validation); $this->assertEquals('exactMatch', $validation->get_scoring_type()); $validResponse = $validation->get_valid_response(); $this->assertNotNull($validResponse); $this->assertEquals(2, $validResponse->get_score()); $this->assertEquals(["Sydney"], $validResponse->get_value()); $altResponses = $validation->get_alt_responses(); $this->assertNotNull($altResponses); $this->assertCount(1, $altResponses); $this->assertEquals(0.5, $altResponses[0]->get_score()); $this->assertEquals(["Canberra"], $altResponses[0]->get_value()); }
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; }