protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { if (($identifier = self::getDOMElementAttributeAs($element, 'identifier')) !== null) { $fqClass = $this->lookupClass($element); try { $component = new $fqClass($identifier); } catch (InvalidArgumentException $e) { $msg = "'{$identifier}' is not a valid identifier for an 'inlineChoice' element."; throw new UnmarshallingException($msg, $element, $e); } try { $component->setContent(new TextOrVariableCollection($children->getArrayCopy())); } catch (InvalidArgumentException $e) { $msg = "'inlineChoice' elements must only contain text or 'printedVariable' elements."; throw new UnmarshallingException($msg, $element, $e); } if (($fixed = self::getDOMElementAttributeAs($element, 'fixed', 'boolean')) !== null) { $component->setFixed($fixed); } if (($templateIdentifier = self::getDOMElementAttributeAs($element, 'templateIdentifier')) !== null) { $component->setTemplateIdentifier($templateIdentifier); } if (($showHide = self::getDOMElementAttributeAs($element, 'showHide')) !== null) { $component->setShowHide(ShowHide::getConstantByName($showHide)); } self::fillBodyElement($component, $element); return $component; } else { $msg = "The mandatory 'identifier' attribute is missing from the 'simpleChoice' element."; throw new UnmarshallingException($msg, $element); } }
protected function buildComponentCollectionWithNonMergeableInteractionTypes() { $collection = new QtiComponentCollection(); $choiceInteraction = ChoiceInteractionBuilder::buildSimple('testChoiceInteractionIdentifier', ['ChoiceOne' => 'A', 'ChoiceTwo' => 'B']); $collection->attach($choiceInteraction); return $collection; }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown() */ protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { // At item authoring time, we could admit that an empty data attribute // may occur. if (($data = self::getDOMElementAttributeAs($element, 'data')) === null) { $data = ''; } if (($type = self::getDOMElementAttributeAs($element, 'type')) !== null) { $fqClass = $this->lookupClass($element); $component = new $fqClass($data, $type); $component->setContent(new ObjectFlowCollection($children->getArrayCopy())); if (($width = self::getDOMElementAttributeAs($element, 'width', 'integer')) !== null) { $component->setWidth($width); } if (($height = self::getDOMElementAttributeAs($element, 'height', 'integer')) !== null) { $component->setHeight($height); } if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } $this->fillBodyElement($component, $element); return $component; } else { $msg = "The mandatory attribute 'type' is missign from the 'object' element."; throw new UnmarshallingException($msg, $element); } }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown() */ protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { if (($identifier = self::getDOMElementAttributeAs($element, 'identifier')) !== null) { $fqClass = $this->lookupClass($element); $component = new $fqClass($identifier); if (($fixed = self::getDOMElementAttributeAs($element, 'fixed', 'boolean')) !== null) { $component->setFixed($fixed); } if (($templateIdentifier = self::getDOMElementAttributeAs($element, 'templateIdentifier')) !== null) { $component->setTemplateIdentifier($templateIdentifier); } if (($showHide = self::getDOMElementAttributeAs($element, 'showHide')) !== null) { $component->setShowHide(ShowHide::getConstantByName($showHide)); } if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } $component->setContent(new InlineStaticCollection($children->getArrayCopy())); $this->fillBodyElement($component, $element); return $component; } else { $msg = "The mandatory 'identifier' attribute is missing from the 'hottext' element."; throw new UnmarshallingException($msg, $element); } }
protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { if (($responseIdentifier = self::getDOMElementAttributeAs($element, 'responseIdentifier')) !== null) { $fqClass = $this->lookupClass($element); $component = new $fqClass($responseIdentifier, new SimpleAssociableChoiceCollection($children->getArrayCopy())); if (($shuffle = self::getDOMElementAttributeAs($element, 'shuffle', 'boolean')) !== null) { $component->setShuffle($shuffle); } if (($maxAssociations = self::getDOMElementAttributeAs($element, 'maxAssociations', 'integer')) !== null) { $component->setMaxAssociations($maxAssociations); } if (($minAssociations = self::getDOMElementAttributeAs($element, 'minAssociations', 'integer')) !== null) { $component->setMinAssociations($minAssociations); } if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } $promptElts = self::getChildElementsByTagName($element, 'prompt'); if (count($promptElts) > 0) { $promptElt = $promptElts[0]; $prompt = $this->getMarshallerFactory()->createMarshaller($promptElt)->unmarshall($promptElt); $component->setPrompt($prompt); } self::fillBodyElement($component, $element); return $component; } else { $msg = "The mandatory 'responseIdentifier' attribute is missing from the 'associateInteraction' element."; throw new UnmarshallingException($msg, $element); } }
protected function buildResponseDeclaration() { $responseDeclartation = ResponseDeclarationBuilder::buildWithCorrectResponse('testChoiceInteractionIdentifier', ['1', '2']); $collection = new QtiComponentCollection(); $collection->attach($responseDeclartation); return $collection; }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown() */ protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { if (($responseIdentifier = self::getDOMElementAttributeAs($element, 'responseIdentifier')) !== null) { $version = $this->getVersion(); $fqClass = $this->lookupClass($element); $choices = new InlineChoiceCollection($children->getArrayCopy()); if (count($choices) === 0) { $msg = "An 'inlineChoiceInteraction' element must contain at least 1 'inlineChoice' elements, none given."; throw new UnmarshallingException($message, $element); } try { $component = new $fqClass($responseIdentifier, $choices); } catch (InvalidArgumentException $e) { $msg = "The value of the attribute 'responseIdentifier' for element 'inlineChoiceInteraction' is not a valid identifier."; throw new UnmarshallingException($msg, $element, $e); } if (($shuffle = self::getDOMElementAttributeAs($element, 'shuffle', 'boolean')) !== null) { $component->setShuffle($shuffle); } elseif (Version::compare($version, '2.1.0', '<') === true) { $msg = "The mandatory 'shuffle' attribute is missing from the 'inlineChoiceInteraction' element."; throw new UnmarshallingException($msg, $element); } if (Version::compare($version, '2.1.0', '>=') === true && ($required = self::getDOMElementAttributeAs($element, 'required', 'boolean')) !== null) { $component->setRequired($required); } if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } $this->fillBodyElement($component, $element); return $component; } else { $msg = "The mandatory 'responseIdentifier' attribute is missing from the 'inlineChoiceInteraction' element."; throw new UnmarshallingException($msg, $element); } }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown() */ protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { $fqClass = $this->lookupClass($element); if ($element->localName === 'a') { if (($href = self::getDOMElementAttributeAs($element, 'href')) !== null) { $component = new $fqClass($href); if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } if (($type = self::getDOMElementAttributeAs($element, 'type')) !== null) { $component->setType($type); } } else { $msg = "The mandatory 'href' attribute of the 'a' element is missing."; throw new UnmarshallingException($msg, $element); } } else { $component = new $fqClass(); } $component->setContent(new InlineCollection($children->getArrayCopy())); $this->fillBodyElement($component, $element); // The q class has a specific cite (URI) attribute. if ($component instanceof Q && ($cite = self::getDOMElementAttributeAs($element, 'cite')) !== null) { try { $component->setCite($cite); } catch (InvalidArgumentException $e) { $msg = "The 'cite' attribute of a 'q' element must be a valid URI, '" . $cite . "' given."; throw new UnmarshallingException($msg, $element, $e); } } return $component; }
protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { if (($identifier = self::getDOMElementAttributeAs($element, 'identifier')) !== null) { if (($matchMax = self::getDOMElementAttributeAs($element, 'matchMax', 'integer')) !== null) { $fqClass = $this->lookupClass($element); $component = new $fqClass($identifier, $matchMax); if (($fixed = self::getDOMElementAttributeAs($element, 'fixed', 'boolean')) !== null) { $component->setFixed($fixed); } if (($templateIdentifier = self::getDOMElementAttributeAs($element, 'templateIdentifier')) !== null) { $component->setTemplateIdentifier($templateIdentifier); } if (($showHide = self::getDOMElementAttributeAs($element, 'showHide')) !== null) { $component->setShowHide(ShowHide::getConstantByName($showHide)); } if (($matchMin = self::getDOMElementAttributeAs($element, 'matchMin', 'integer')) !== null) { $component->setMatchMin($matchMin); } $component->setContent(new FlowStaticCollection($children->getArrayCopy())); self::fillBodyElement($component, $element); return $component; } else { $msg = "The mandatory 'matchMax' attribute is missing from the 'simpleAssociableChoice' element."; throw new UnmarshallingException($msg, $element); } } else { $msg = "The mandatory 'identifier' attribute is missing from the 'simpleAssociableChoice' element."; throw new UnmarshallingException($msg, $element); } }
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()); } }
protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { if (($responseIdentifier = self::getDOMElementAttributeAs($element, 'responseIdentifier')) !== null) { $gapChoiceElts = self::getChildElementsByTagName($element, array('gapText', 'gapImg')); if (count($gapChoiceElts) > 0) { $gapChoices = new GapChoiceCollection(); foreach ($gapChoiceElts as $g) { $gapChoices[] = $this->getMarshallerFactory()->createMarshaller($g)->unmarshall($g); } $fqClass = $this->lookupClass($element); $component = new $fqClass($responseIdentifier, $gapChoices, new BlockStaticCollection($children->getArrayCopy())); $promptElts = self::getChildElementsByTagName($element, 'prompt'); if (count($promptElts) === 1) { $component->setPrompt($this->getMarshallerFactory()->createMarshaller($promptElts[0])->unmarshall($promptElts[0])); } if (($shuffle = self::getDOMElementAttributeAs($element, 'shuffle', 'boolean')) !== null) { $component->setShuffle($shuffle); } if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } self::fillBodyElement($component, $element); return $component; } else { $msg = "A 'gapMatchInteraction' element must contain at least 1 'gapChoice' element, none given."; throw new UnmarshallingException($msg, $element); } } else { $msg = "The mandatory 'responseIdentifier' attribute is missing from the 'gapMatchInteraction' element."; throw new UnmarshallingException($msg, $element); } }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown() */ protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { $fqClass = $this->lookupClass($element); $component = new $fqClass(); $component->setContent(new FlowCollection($children->getArrayCopy())); $this->fillBodyElement($component, $element); return $component; }
private function getUniqueInteractionTypes(QtiComponentCollection $interactionComponents) { // Decide whether we shall merge interaction $interactionTypes = array_unique(array_map(function ($component) { /* @var $component Interaction */ return $component->getQtiClassName(); }, $interactionComponents->getArrayCopy())); return $interactionTypes; }
protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { $fqClass = $this->lookupClass($element); $component = new $fqClass(); $childrenArray = $children->getArrayCopy(); $component->setContent($component instanceof Dt ? new InlineCollection($childrenArray) : new FlowCollection($childrenArray)); self::fillBodyElement($component, $element); return $component; }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown() */ protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { $version = $this->getVersion(); 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]); try { $choices = new HotspotChoiceCollection($children->getArrayCopy()); } catch (InvalidArgumentException $e) { $msg = "A 'graphicOrderInteraction' element can only contain 'hotspotChoice' choices."; throw new UnmarshallingException($msg, $element, $e); } if (count($choices) > 0) { $fqClass = $this->lookupClass($element); $component = new $fqClass($responseIdentifier, $object, $choices); if (Version::compare($version, '2.1.0', '>=') === true) { if (($minChoices = self::getDOMElementAttributeAs($element, 'minChoices', 'integer')) !== null) { // graphicOrderInteraction->minChoices = 0 is an endless debate: // The Information models says: If specfied, minChoices must be 1 or greater but ... // The XSD 2.1 says: xs:integer, [-inf, +inf], optional // The XSD 2.1.1 says: xs:nonNegativeInteger, [0, +inf] // // --> Let's say that if <= 0, we consider it not specfied! if ($minChoices > 0) { $component->setMinChoices($minChoices); } } if (($maxChoices = self::getDOMElementAttributeAs($element, 'maxChoices', 'integer')) !== null) { $component->setMaxChoices($maxChoices); } } if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } $promptElts = self::getChildElementsByTagName($element, 'prompt'); if (count($promptElts) > 0) { $promptElt = $promptElts[0]; $prompt = $this->getMarshallerFactory()->createMarshaller($promptElt)->unmarshall($promptElt); $component->setPrompt($prompt); } $this->fillBodyElement($component, $element); return $component; } else { $msg = "A 'graphicOrderInteraction' must contain at least one 'hotspotChoice' element, none given."; throw new UnmarshallingException($msg, $element); } } else { $msg = "A 'graphicOrderInteraction' element must contain exactly one 'object' element, none given."; throw new UnmarshallingException($msg, $element); } } else { $msg = "The mandatory 'responseIdentifier' attribute is missing from the 'graphicOrderInteraction' element."; throw new UnmarshallingException($msg, $element); } }
protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { if (($responseIdentifier = self::getDOMElementAttributeAs($element, 'responseIdentifier')) !== null) { $fqClass = $this->lookupClass($element); $component = new $fqClass($responseIdentifier, new SimpleChoiceCollection($children->getArrayCopy())); if (($shuffle = self::getDOMElementAttributeAs($element, 'shuffle', 'boolean')) !== null) { $component->setShuffle($shuffle); } if (($maxChoices = self::getDOMElementAttributeAs($element, 'maxChoices', 'integer')) !== null) { if ($element->localName === 'orderInteraction') { if ($maxChoices !== 0) { $component->setMaxChoices($maxChoices); } } else { $component->setMaxChoices($maxChoices); } } if (($minChoices = self::getDOMElementAttributeAs($element, 'minChoices', 'integer')) !== null) { if ($element->localName === 'orderInteraction') { /* * Lots of QTI implementations output minChoices = 0 while * dealing with orderInteraction unmarshalling. However, regarding * the IMS QTI Specification, it is invalid. * * "If specified, minChoices must be 1 or greater but must not exceed the * number of choices available." * * See http://www.imsglobal.org/question/qtiv2p1/imsqti_infov2p1.html#element10283 */ if ($minChoices !== 0) { $component->setMinChoices($minChoices); } } else { $component->setMinChoices($minChoices); } } if (($orientation = self::getDOMElementAttributeAs($element, 'orientation')) !== null) { $component->setOrientation(Orientation::getConstantByName($orientation)); } if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } $promptElts = self::getChildElementsByTagName($element, 'prompt'); if (count($promptElts) > 0) { $promptElt = $promptElts[0]; $prompt = $this->getMarshallerFactory()->createMarshaller($promptElt)->unmarshall($promptElt); $component->setPrompt($prompt); } self::fillBodyElement($component, $element); return $component; } else { $msg = "The mandatory 'responseIdentifier' attribute is missing from the " . $element->localName . " element."; throw new UnmarshallingException($msg, $element); } }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown() */ protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { try { $component = new Tr(new TableCellCollection($children->getArrayCopy())); $this->fillBodyElement($component, $element); return $component; } catch (InvalidArgumentException $e) { $msg = "A 'tr' element must contain at least one 'td' or 'th' element."; throw new UnmarshallingException($msg, $element); } }
protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { $fqClass = $this->lookupClass($element); $component = new $fqClass(); $component->setContent(new FlowCollection($children->getArrayCopy())); if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } self::fillBodyElement($component, $element); return $component; }
public function buildContentCollection(QtiComponentCollection $contentCollection) { // Check whether the content is already an InlineCollection $areInlineComponents = array_reduce($contentCollection->getArrayCopy(), function ($initial, $component) { return $initial && $component instanceof Inline; }, true); if ($areInlineComponents) { return $contentCollection; } // Otherwise, make it inline - impossible to make things inline if contents are block elements // TODO: Give up for now throw new \Exception('Fail to build inline content'); }
protected function getMergedInteractionType(QtiComponentCollection $interactionComponents) { // Decide whether we shall merge interaction $interactionTypes = array_unique(array_map(function ($component) { /* @var $component Interaction */ return $component->getQtiClassName(); }, $interactionComponents->getArrayCopy())); if (count($interactionTypes) === 1 && in_array($interactionTypes[0], Constants::$needMergeInteractionTypes)) { return $interactionTypes[0]; } else { return false; } }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown() */ protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { $fqClass = $this->lookupClass($element); $component = new $fqClass(); $component->setContent(new FlowStaticCollection($children->getArrayCopy())); if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } $this->fillBodyElement($component, $element); if (($title = static::getDOMElementAttributeAs($element, 'title')) !== null) { $component->setTitle($title); } return $component; }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown() */ protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { $version = $this->getVersion(); 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]); if (($maxChoices = self::getDOMElementAttributeAs($element, 'maxChoices', 'integer')) !== null) { try { $choices = new HotspotChoiceCollection($children->getArrayCopy()); } catch (InvalidArgumentException $e) { $msg = "An 'hotspotInteraction' element can only contain 'hotspotChoice' choices."; throw new UnmarshallingException($msg, $element, $e); } if (count($choices) > 0) { $fqClass = $this->lookupClass($element); $component = new $fqClass($responseIdentifier, $object, $maxChoices, $choices); if (Version::compare($version, '2.1.0', '>=') === true && ($minChoices = self::getDOMElementAttributeAs($element, 'minChoices', 'integer')) !== null) { $component->setMinChoices($minChoices); } if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } $promptElts = self::getChildElementsByTagName($element, 'prompt'); if (count($promptElts) > 0) { $promptElt = $promptElts[0]; $prompt = $this->getMarshallerFactory()->createMarshaller($promptElt)->unmarshall($promptElt); $component->setPrompt($prompt); } $this->fillBodyElement($component, $element); return $component; } else { $msg = "An 'hotspotInteraction' element must contain at least one 'hotspotChoice' element, none given"; throw new UnmarshallingException($msg, $element); } } else { $msg = "The mandatory 'maxChoices' attribute is missing from the 'hotspotInteraction' element."; throw new UnmarshallingException($msg, $element); } } else { $msg = "A 'hotspotInteraction' element must contain exactly one 'object' element, none given."; throw new UnmarshallingException($msg, $element); } } else { $msg = "The mandatory 'responseIdentifier' attribute is missing from the '" . $element->localName . "' element."; throw new UnmarshallingException($msg, $element); } }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown() */ protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { $version = $this->getVersion(); // responseIdentifier. if (($responseIdentifier = self::getDOMElementAttributeAs($element, 'responseIdentifier')) !== null) { $fqClass = $this->lookupClass($element); try { $component = new $fqClass($responseIdentifier, new SimpleMatchSetCollection($children->getArrayCopy())); } catch (InvalidArgumentException $e) { $msg = "A matchInteraction element must contain exactly 2 simpleMatchSet elements, " . count($children) . "' given."; throw new UnmarshallingException($msg, $element, $e); } // shuffle. if (($shuffle = self::getDOMElementAttributeAs($element, 'shuffle', 'boolean')) !== null) { $component->setShuffle($shuffle); } elseif (Version::compare($version, '2.1.0', '<') === true) { $msg = "The mandatory attribute 'shuffle' is missing from the 'matchInteraction' element."; throw new UnmarshallingException($msg, $element); } // maxAssociations. if (($maxAssociations = self::getDOMElementAttributeAs($element, 'maxAssociations', 'integer')) !== null) { $component->setMaxAssociations($maxAssociations); } elseif (Version::compare($version, '2.1.0', '<') === true) { $msg = "The mandatory attribute 'maxAssociations' is missing from the 'matchInteraction' element."; throw new UnmarshallingException($msg, $element); } // minAssociations. if (Version::compare($version, '2.1.0', '>=') === true && ($minAssociations = self::getDOMElementAttributeAs($element, 'minAssociations', 'integer')) !== null) { $component->setMinAssociations($minAssociations); } // xml:base if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } // prompt. $promptElts = self::getChildElementsByTagName($element, 'prompt'); if (count($promptElts) > 0) { $promptElt = $promptElts[0]; $prompt = $this->getMarshallerFactory()->createMarshaller($promptElt)->unmarshall($promptElt); $component->setPrompt($prompt); } $this->fillBodyElement($component, $element); return $component; } else { $msg = "The mandatory 'responseIdentifier' attribute is missing from the 'matchInteraction' element."; throw new UnmarshallingException($msg, $element); } }
protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { 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]); try { $choices = new AssociableHotspotCollection($children->getArrayCopy()); } catch (InvalidArgumentException $e) { $msg = "An 'graphicAssociateInteraction' element can only contain 'associableHotspot' choices."; throw new UnmarshallingException($msg, $element, $e); } if (count($choices) > 0) { $fqClass = $this->lookupClass($element); $component = new $fqClass($responseIdentifier, $object, $choices); if (($minAssociations = self::getDOMElementAttributeAs($element, 'minAssociations', 'integer')) !== null) { $component->setMinAssociations($minAssociations); } if (($maxAssociations = self::getDOMElementAttributeAs($element, 'maxAssociations', 'integer')) !== null) { $component->setMaxAssociations($maxAssociations); } if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } $promptElts = self::getChildElementsByTagName($element, 'prompt'); if (count($promptElts) > 0) { $promptElt = $promptElts[0]; $prompt = $this->getMarshallerFactory()->createMarshaller($promptElt)->unmarshall($promptElt); $component->setPrompt($prompt); } self::fillBodyElement($component, $element); return $component; } else { $msg = "A 'graphicAssociateInteraction' element must contain at lease one 'associableHotspot' element, none given."; } } else { $msg = "A 'graphicAssociateInteraction' element must contain exactly one 'object' element, none given."; throw new UnmarshallingException($msg, $element); } } else { $msg = "The mandatory 'responseIdentifier' attribute is missing from the 'graphicAssociateInteraction' element."; throw new UnmarshallingException($msg, $element); } }
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]; }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown() */ protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { $fqClass = $this->lookupClass($element); $component = new $fqClass(); if (($headers = self::getDOMElementAttributeAs($element, 'headers')) !== null) { try { $headersCollection = new IdentifierCollection(); foreach (explode(" ", $headers) as $h) { $headersCollection[] = $h; } $component->setHeaders($headersCollection); } catch (InvalidArgumentException $e) { $msg = "The 'headers' attribute does not contain valid QTI identifiers."; throw new UnmarshallingException($msg, $element); } } if (($scope = self::getDOMElementAttributeAs($element, 'scope')) !== null) { $component->setScope(TableCellScope::getConstantByName($scope)); } if (($abbr = self::getDOMElementAttributeAs($element, 'abbr')) !== null) { $component->setAbbr($abbr); } if (($axis = self::getDOMElementAttributeAs($element, 'axis')) !== null) { $component->setAxis($axis); } if (($rowspan = self::getDOMElementAttributeAs($element, 'rowspan', 'integer')) !== null) { $component->setRowspan($rowspan); } if (($colspan = self::getDOMElementAttributeAs($element, 'colspan', 'integer')) !== null) { $component->setColspan($colspan); } try { $component->setContent(new FlowCollection($children->getArrayCopy())); $this->fillBodyElement($component, $element); return $component; } catch (InvalidArgumentException $e) { $msg = "A '" . $element->localName . "' element can only contain QTI flow elements."; throw new UnmarshallingException($msg, $element); } }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown() */ protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { $version = $this->getVersion(); if (($responseIdentifier = self::getDOMElementAttributeAs($element, 'responseIdentifier')) !== null) { $fqClass = $this->lookupClass($element); try { $content = new BlockStaticCollection($children->getArrayCopy()); } catch (InvalidArgumentException $e) { $msg = "The content of the 'hottextInteraction' element is invalid."; throw new UnmarshallingException($msg, $element, $e); } try { $component = new $fqClass($responseIdentifier, $content); } catch (InvalidArgumentException $e) { $msg = "The value '{$responseIdentifier}' for the attribute 'responseIdentifier' for element 'hottextInteraction' is not a valid QTI identifier."; throw new UnmarshallingException($msg, $element, $e); } if (($maxChoices = self::getDOMElementAttributeAs($element, 'maxChoices', 'integer')) !== null) { $component->setMaxChoices($maxChoices); } if (Version::compare($version, '2.1.0', '>=') === true && ($minChoices = self::getDOMElementAttributeAs($element, 'minChoices', 'integer')) !== null) { $component->setMinChoices($minChoices); } if (($xmlBase = self::getXmlBase($element)) !== false) { $component->setXmlBase($xmlBase); } $promptElts = self::getChildElementsByTagName($element, 'prompt'); if (count($promptElts) > 0) { $promptElt = $promptElts[0]; $prompt = $this->getMarshallerFactory()->createMarshaller($promptElt)->unmarshall($promptElt); $component->setPrompt($prompt); } $this->fillBodyElement($component, $element); return $component; } else { $msg = "The mandatory 'responseIdentifier' attribute is missing from the " . $element->localName . " element."; throw new UnmarshallingException($msg, $element); } }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown() */ protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { $version = $this->getVersion(); if (($identifier = self::getDOMElementAttributeAs($element, 'identifier')) !== null) { $fqClass = $this->lookupClass($element); $component = new $fqClass($identifier); if (($fixed = self::getDOMElementAttributeAs($element, 'fixed', 'boolean')) !== null) { $component->setFixed($fixed); } if (Version::compare($version, '2.1.0', '>=') === true && ($templateIdentifier = self::getDOMElementAttributeAs($element, 'templateIdentifier')) !== null) { $component->setTemplateIdentifier($templateIdentifier); } if (Version::compare($version, '2.1.0', '>=') === true && ($showHide = self::getDOMElementAttributeAs($element, 'showHide')) !== null) { $component->setShowHide(ShowHide::getConstantByName($showHide)); } $component->setContent(new FlowStaticCollection($children->getArrayCopy())); $this->fillBodyElement($component, $element); return $component; } else { $msg = "The mandatory 'identifier' attribute is missing from the 'simpleChoice' element."; throw new UnmarshallingException($msg, $element); } }
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; }
protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children) { $fqClass = $this->lookupClass($element); if (($outcomeIdentifier = self::getDOMElementAttributeAs($element, 'outcomeIdentifier')) !== null) { if (($identifier = self::getDOMElementAttributeAs($element, 'identifier')) !== null) { $component = new $fqClass($outcomeIdentifier, $identifier); if (($showHide = self::getDOMElementAttributeAs($element, 'showHide')) !== null) { try { $component->setShowHide(ShowHide::getConstantByName($showHide)); } catch (InvalidArgumentException $e) { $msg = "'{$showHide}' is not a valid value for the 'showHide' attribute of element 'modalFeedback'."; throw new UnmarshallingException($msg, $element, $e); } try { $content = new FlowStaticCollection($children->getArrayCopy()); $component->setContent($content); } catch (InvalidArgumentException $e) { $msg = "The content of the 'modalFeedback' is invalid. It must only contain 'flowStatic' elements."; throw new UnmarshallingException($msg, $element, $e); } if (($title = self::getDOMElementAttributeAs($element, 'title')) !== null) { $component->setTitle($title); } return $component; } else { $msg = "The mandatory 'showHide' attribute is missing from element 'modalFeedback'."; } } else { $msg = "The mandatory 'identifier' attribute is missing from element 'modalFeedback'."; throw new UnmarshallingException($msg, $element); } } else { $msg = "The mandatory 'outcomeIdentifier' attribute is missing from element 'modalFeedback'."; throw new UnmarshallingException($msg, $element); } }