private function getFeatureReplacementString($node) { // Process inline feature if (isset($node->attr['data-type']) && isset($node->attr['data-src'])) { $src = trim($node->attr['data-src']); $type = trim($node->attr['data-type']); if ($type === 'audioplayer' || $type === 'audioplayer') { return QtiMarshallerUtil::marshallValidQti(new Object($src, MimeUtil::guessMimeType(basename($src)))); } // Process regular question feature } else { $nodeClassAttribute = $node->attr['class']; $featureReference = $this->getFeatureReferenceFromClassName($nodeClassAttribute); $feature = $this->widgets[$featureReference]; $type = $feature['data']['type']; if ($type === 'audioplayer' || $type === 'audioplayer') { $src = $feature['data']['src']; $object = new Object($src, MimeUtil::guessMimeType(basename($src))); $object->setLabel($featureReference); return QtiMarshallerUtil::marshallValidQti($object); } else { if ($type === 'sharedpassage') { $content = $feature['data']['content']; $object = new Object('', 'text/html'); $object->setContent(ContentCollectionBuilder::buildObjectFlowCollectionContent(QtiMarshallerUtil::unmarshallElement($content))); $object->setLabel($featureReference); return QtiMarshallerUtil::marshallValidQti($object); } } } throw new MappingException($type . ' not supported'); }
public static function buildQtiImageObject($data, $type) { $object = new Object($data, $type); $objectFlowCollection = new ObjectFlowCollection(); $objectFlowCollection->attach(new TextRun('qwe')); $object->setContent($objectFlowCollection); return $object; }
protected function buildTemplate(QtiGraphicGapMatchInteraction $interaction, Object $object) { $associableHotspots = []; foreach ($interaction->getAssociableHotspots() as $associableHotspot) { /** @var AssociableHotspot $associableHotspot */ $associableHotspots[$associableHotspot->getIdentifier()] = QtiCoordinateUtil::convertQtiCoordsToPercentage([$object->getWidth(), $object->getHeight()], explode(',', $associableHotspot->getCoords()), $associableHotspot->getShape()); } return $associableHotspots; }
public static function buildWithPolyShapesChoices($responseIdentifier) { $imageObject = new Object('http://anyurl.com', 'image/png'); $imageObject->setWidth(131); $imageObject->setHeight(37); $collection = new HotspotChoiceCollection(); $collection->attach(new HotspotChoice('A', QtiShape::POLY, new QtiCoords(QtiShape::POLY, [7, 12, 64, 12, 64, 28, 7, 28]))); $collection->attach(new HotspotChoice('B', QtiShape::POLY, new QtiCoords(QtiShape::POLY, [66, 11, 125, 11, 125, 30, 66, 30]))); return new HotspotInteraction($responseIdentifier, $imageObject, 0, $collection); }
public function testMarshallSimple() { $param1 = new Param('movie', 'movie.swf', ParamType::REF); $param2 = new Param('quality', 'high', ParamType::DATA); $object = new Object('http://mywebsite.com/movie.swf', 'application/x-shockwave-flash', 'flash-movie'); $object->setContent(new ObjectFlowCollection(array($param1, $param2))); $element = $this->getMarshallerFactory()->createMarshaller($object)->marshall($object); $dom = new DOMDocument('1.0', 'UTF-8'); $element = $dom->importNode($element, true); $this->assertEquals('<object data="http://mywebsite.com/movie.swf" type="application/x-shockwave-flash" id="flash-movie"><param name="movie" value="movie.swf" valuetype="REF"/><param name="quality" value="high" valuetype="DATA"/></object>', $dom->saveXml($element)); }
public function testMarshall() { $interactionObject = new Object('airplane.jpg', 'image/jpeg'); $interactionObject->setHeight(16); $interactionObject->setWidth(16); $interaction = new PositionObjectInteraction('RESPONSE', $interactionObject); $interaction->setCenterPoint(new Point(8, 8)); $stageObject = new Object('country.jpg', 'image/jpeg'); $positionObjectStage = new PositionObjectStage($stageObject, new PositionObjectInteractionCollection(array($interaction))); $element = $this->getMarshallerFactory('2.1.0')->createMarshaller($positionObjectStage)->marshall($positionObjectStage); $dom = new DOMDocument('1.0', 'UTF-8'); $element = $dom->importNode($element, true); $this->assertEquals('<positionObjectStage><object data="country.jpg" type="image/jpeg"/><positionObjectInteraction responseIdentifier="RESPONSE" maxChoices="1" centerPoint="8 8"><object data="airplane.jpg" type="image/jpeg" width="16" height="16"/></positionObjectInteraction></positionObjectStage>', $dom->saveXML($element)); }
/** * @depends testMarshall21 */ public function testMarshall20() { // Make sure minChoices is not taken into account in a QTI 2.0 context. $object = new Object('myimg.jpg', 'image/jpeg'); $object->setWidth(400); $object->setHeight(300); $positionObjectInteraction = new PositionObjectInteraction('RESPONSE', $object); $positionObjectInteraction->setMaxChoices(2); $positionObjectInteraction->setMinChoices(1); $element = $this->getMarshallerFactory('2.0.0')->createMarshaller($positionObjectInteraction)->marshall($positionObjectInteraction); $dom = new DOMDocument('1.0', 'UTF-8'); $element = $dom->importNode($element, true); $this->assertEquals('<positionObjectInteraction responseIdentifier="RESPONSE" maxChoices="2"><object data="myimg.jpg" type="image/jpeg" width="400" height="300"/></positionObjectInteraction>', $dom->saveXML($element)); }
public function testMarshall() { $object = new Object('myimg.jpg', 'image/jpeg'); $object->setWidth(400); $object->setHeight(300); $prompt = new Prompt(); $prompt->setContent(new FlowStaticCollection(array(new TextRun('Prompt...')))); $positionObjectInteraction = new PositionObjectInteraction('RESPONSE', $object, 'my-pos'); $positionObjectInteraction->setCenterPoint(new Point(150, 74)); $positionObjectInteraction->setMaxChoices(2); $positionObjectInteraction->setMinChoices(1); $element = $this->getMarshallerFactory()->createMarshaller($positionObjectInteraction)->marshall($positionObjectInteraction); $dom = new DOMDocument('1.0', 'UTF-8'); $element = $dom->importNode($element, true); $this->assertEquals('<positionObjectInteraction responseIdentifier="RESPONSE" maxChoices="2" minChoices="1" centerPoint="150 74" id="my-pos"><object data="myimg.jpg" type="image/jpeg" width="400" height="300"/></positionObjectInteraction>', $dom->saveXML($element)); }
public function testMatchCorrectValidation() { $bgObject = new Object('http://img.png', 'image/png'); $bgObject->setWidth(100); $bgObject->setHeight(200); $testInteraction = GraphicGapInteractionBuilder::build('testInteraction', $bgObject, ['A' => 'img_A.png', 'B' => 'img_B.png'], ['G1' => [0, 0, 10, 10], 'G2' => [30, 40, 50, 60]]); $responseProcessingTemplate = ResponseProcessingTemplate::matchCorrect(); $validResponseIdentifier = [new QtiDirectedPair('A', 'G1'), new QtiDirectedPair('A', 'G2'), new QtiDirectedPair('B', 'G1')]; $responseDeclaration = ResponseDeclarationBuilder::buildWithCorrectResponse('testIdentifier', $validResponseIdentifier); $mapper = new GraphicGapMatchInteractionMapper($testInteraction, $responseDeclaration, $responseProcessingTemplate); /** @var imageclozeassociation $q */ $q = $mapper->getQuestionType(); $this->assertEquals('imageclozeassociation', $q->get_type()); $this->assertEquals(['<img src="img_A.png"/>', '<img src="img_B.png"/>'], $q->get_possible_responses()); $this->assertTrue($q->get_duplicate_responses()); $this->assertEquals([['x' => 0, 'y' => 0], ['x' => 30, 'y' => 20]], $q->get_response_positions()); $img = $q->get_image(); $this->assertInstanceOf('LearnosityQti\\Entities\\QuestionTypes\\imageclozeassociation_image', $img); $this->assertEquals('http://img.png', $img->get_src()); /** @var imageclozeassociation_validation $validation */ $validation = $q->get_validation(); $this->assertInstanceOf('LearnosityQti\\Entities\\QuestionTypes\\imageclozeassociation_validation', $validation); $this->assertEquals('exactMatch', $validation->get_scoring_type()); /** @var imageclozeassociation_validation_valid_response $validResponse */ $validResponse = $validation->get_valid_response(); $this->assertInstanceOf('LearnosityQti\\Entities\\QuestionTypes\\imageclozeassociation_validation_valid_response', $validResponse); $this->assertEquals(1, $validResponse->get_score()); $this->assertEquals(['<img src="img_A.png"/>', '<img src="img_A.png"/>'], $validResponse->get_value()); $altResponses = $validation->get_alt_responses(); $this->assertCount(1, $altResponses); $this->assertEquals(1, $altResponses[0]->get_score()); $this->assertEquals(['<img src="img_B.png"/>', '<img src="img_A.png"/>'], $altResponses[0]->get_value()); }
public function testMarshall() { $object = new Object('my-video.mp4', 'video/mp4'); $object->setWidth(400); $object->setHeight(300); $mediaInteraction = new MediaInteraction('RESPONSE', false, $object, 'my-media'); $mediaInteraction->setMinPlays(1); $mediaInteraction->setMaxPlays(2); $mediaInteraction->setLoop(true); $prompt = new Prompt(); $prompt->setContent(new FlowStaticCollection(array(new TextRun('Prompt...')))); $mediaInteraction->setPrompt($prompt); $element = $this->getMarshallerFactory('2.1.0')->createMarshaller($mediaInteraction)->marshall($mediaInteraction); $dom = new DOMDocument('1.0', 'UTF-8'); $element = $dom->importNode($element, true); $this->assertEquals('<mediaInteraction id="my-media" responseIdentifier="RESPONSE" autostart="false" minPlays="1" maxPlays="2" loop="true"><prompt>Prompt...</prompt><object data="my-video.mp4" type="video/mp4" width="400" height="300"/></mediaInteraction>', $dom->saveXML($element)); }
private function checkObjectComponents(Object $object, $conversionTo) { if (!empty($object->getComponents())) { LogService::log('Converting <object> element to ' . $conversionTo . '. Any contents within it are removed'); } }
private function convertTextToObjectWithBase64ImageString($text) { $string = $text; $font = 3; $width = ImageFontWidth($font) * strlen($string); $height = ImageFontHeight($font); ob_start(); $im = @imagecreate($width, $height); $background_color = imagecolorallocate($im, 255, 255, 255); // White background $text_color = imagecolorallocate($im, 0, 0, 0); // Black text imagestring($im, $font, 0, 0, $string, $text_color); imagepng($im); $imagedata = ob_get_contents(); ob_end_clean(); $imagedata = 'data:image/png;base64,' . base64_encode($imagedata); $gapImageObject = new Object($imagedata, 'image/png'); $gapImageObject->setWidth($width); $gapImageObject->setHeight($height); return $gapImageObject; }
private function transformCoordinates(QtiCoords $coords, $shape, Object $imageObject) { $width = $imageObject->getWidth(); $height = $imageObject->getHeight(); $coords = explode(',', $coords); switch ($shape) { // rect: left-x, top-y, right-x, bottom-y. case QtiShape::RECT: $leftX = round($coords[0] / $width * 100, 2); $topY = round($coords[1] / $height * 100, 2); $rightX = round($coords[2] / $width * 100, 2); $bottomY = round($coords[3] / $height * 100, 2); $result = [['x' => $leftX, 'y' => $topY], ['x' => $rightX, 'y' => $topY], ['x' => $rightX, 'y' => $bottomY], ['x' => $leftX, 'y' => $bottomY]]; return $result; case QtiShape::CIRCLE: // circle: center-x, center-y, radius. Note. When the radius value is a percentage value, user agents // should calculate the final radius value based on the associated object's width and height. The radius should be the smaller value of the two. LogService::log('Unable to map QTI `circle` Shape. Mapping it as `rect` instead'); $radius = $coords[2]; $leftX = round(($coords[0] - $radius) / $width * 100, 2); $topY = round(($coords[1] + $radius) / $height * 100, 2); $rightX = round(($coords[0] + $radius) / $width * 100, 2); $bottomY = round(($coords[1] - $radius) / $height * 100, 2); $result = [['x' => $leftX, 'y' => $topY], ['x' => $rightX, 'y' => $topY], ['x' => $rightX, 'y' => $bottomY], ['x' => $leftX, 'y' => $bottomY]]; return $result; case QtiShape::POLY: // poly: x1, y1, x2, y2, ..., xN, yN. The first x and y coordinate pair and the last should be the same to close the polygon. // When these coordinate values are not the same, user agents should infer an additional coordinate pair to close the polygon. $result = []; for ($i = 0; $i < count($coords); $i += 2) { $result[] = ['x' => round($coords[$i] / $width * 100, 2), 'y' => round($coords[$i + 1] / $height * 100, 2)]; } return $result; case QtiShape::ELLIPSE: default: LogService::log('Unsupported QTI Shape mapping conversion. Area mapping conversion is ignored'); return []; } }