/** * Unmarshall a DOMElement object corresponding to a graphicGapMatchInteraction element. * * @param \DOMElement $element A DOMElement object. * @return \qtism\data\QtiComponent A GraphicGapMatchInteraction object. * @throws \qtism\data\storage\xml\marshalling\UnmarshallingException */ protected function unmarshall(DOMElement $element) { if (($responseIdentifier = self::getDOMElementAttributeAs($element, 'responseIdentifier')) !== null) { $objectElts = self::getChildElementsByTagName($element, 'object'); if (count($objectElts) > 0) { $object = $this->getMarshallerFactory()->createMarshaller($objectElts[0])->unmarshall($objectElts[0]); $associableHotspotElts = self::getChildElementsByTagName($element, 'associableHotspot'); if (count($associableHotspotElts) > 0) { $associableHotspots = new AssociableHotspotCollection(); foreach ($associableHotspotElts as $associableHotspotElt) { $associableHotspots[] = $this->getMarshallerFactory()->createMarshaller($associableHotspotElt)->unmarshall($associableHotspotElt); } $gapImgElts = self::getChildElementsByTagName($element, 'gapImg'); if (count($gapImgElts) > 0) { $gapImgs = new GapImgCollection(); foreach ($gapImgElts as $gapImgElt) { $gapImgs[] = $this->getMarshallerFactory()->createMarshaller($gapImgElt)->unmarshall($gapImgElt); } $component = new GraphicGapMatchInteraction($responseIdentifier, $object, $gapImgs, $associableHotspots); $promptElts = self::getChildElementsByTagName($element, 'prompt'); if (count($promptElts) > 0) { $promptElt = $promptElts[0]; $prompt = $this->getMarshallerFactory()->createMarshaller($promptElt)->unmarshall($promptElt); $component->setPrompt($prompt); } if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } $this->fillBodyElement($component, $element); return $component; } else { $msg = "A 'graphicGapMatchInteraction' element must contain at least one 'gapImg' element, none given."; throw new UnmarshallingException($msg, $element); } } else { $msg = "A 'graphiGapMatchInteraction' element must contain at least one 'associableHotspot' element, none given."; throw new UnmarshallingException($msg, $element); } } else { $msg = "A 'graphicGapMatchInteraction' element must contain exactly one 'object' element, none given."; throw new UnmarshallingException($msg, $element); } } else { $msg = "The mandatory 'responseIdentifier' attribute is missing from the 'graphicGapMatchInteraction' element."; throw new UnmarshallingException($msg, $element); } }
public function convert(BaseQuestionType $questionType, $interactionIdentifier, $interactionLabel) { //TODO: Need validation a question shall have at least 1 {{response}} and 1 item in `possible_responses` /** @var imageclozeassociation $question */ $question = $questionType; // Map `possible_responses` to `gapImg`(s) $possibleResponses = $question->get_possible_responses(); $matchMax = !is_null($question->get_duplicate_responses()) ? count($possibleResponses) : 1; $gapImageCollection = $this->buildGapImgCollection($possibleResponses, $matchMax); // Build the main background image `object` $imageObject = $this->buildMainImageObject($question->get_image()); // Build associable hotspots based on `response_positions` $associableHotspotCollection = $this->buildAssociableHotspotCollection($question->get_response_positions(), $imageObject->getWidth(), $imageObject->getHeight()); // Build dah` interaction $interaction = new GraphicGapMatchInteraction($interactionIdentifier, $imageObject, $gapImageCollection, $associableHotspotCollection); $interaction->setLabel($interactionLabel); $interaction->setPrompt($this->convertStimulusForPrompt($question->get_stimulus())); $validationBuilder = new ImageclozeassociationValidationBuilder($possibleResponses); list($responseDeclaration, $responseProcessing) = $validationBuilder->buildValidation($interaction->getResponseIdentifier(), $question->get_validation()); return [$interaction, $responseDeclaration, $responseProcessing]; }
public function testMarshall() { $prompt = new Prompt(); $prompt->setContent(new FlowStaticCollection(array(new TextRun('Prompt...')))); $object = new Object('myimg.png', 'image/png'); $img1 = new Object('img1.png', 'image/png'); $gapImg1 = new GapImg('gapImg1', 1, $img1); $img2 = new Object('img2.png', 'image/png'); $gapImg2 = new GapImg('gapImg2', 1, $img2); $img3 = new Object('img3.png', 'image/png'); $gapImg3 = new GapImg('gapImg3', 1, $img3); $gapImgs = new GapImgCollection(array($gapImg1, $gapImg2, $gapImg3)); $choice1 = new AssociableHotspot('choice1', 1, QtiShape::CIRCLE, new QtiCoords(QtiShape::CIRCLE, array(0, 0, 15))); $choice2 = new AssociableHotspot('choice2', 1, QtiShape::CIRCLE, new QtiCoords(QtiShape::CIRCLE, array(2, 2, 15))); $choice3 = new AssociableHotspot('choice3', 1, QtiShape::CIRCLE, new QtiCoords(QtiShape::CIRCLE, array(4, 4, 15))); $choices = new AssociableHotspotCollection(array($choice1, $choice2, $choice3)); $graphicGapMatchInteraction = new GraphicGapMatchInteraction('RESPONSE', $object, $gapImgs, $choices, 'my-gaps'); $graphicGapMatchInteraction->setPrompt($prompt); $element = $this->getMarshallerFactory('2.1.0')->createMarshaller($graphicGapMatchInteraction)->marshall($graphicGapMatchInteraction); $dom = new DOMDocument('1.0', 'UTF-8'); $element = $dom->importNode($element, true); $this->assertEquals('<graphicGapMatchInteraction id="my-gaps" responseIdentifier="RESPONSE"><prompt>Prompt...</prompt><object data="myimg.png" type="image/png"/><gapImg identifier="gapImg1" matchMax="1"><object data="img1.png" type="image/png"/></gapImg><gapImg identifier="gapImg2" matchMax="1"><object data="img2.png" type="image/png"/></gapImg><gapImg identifier="gapImg3" matchMax="1"><object data="img3.png" type="image/png"/></gapImg><associableHotspot identifier="choice1" shape="circle" coords="0,0,15" matchMax="1"/><associableHotspot identifier="choice2" shape="circle" coords="2,2,15" matchMax="1"/><associableHotspot identifier="choice3" shape="circle" coords="4,4,15" matchMax="1"/></graphicGapMatchInteraction>', $dom->saveXML($element)); }