/** * Create the OperatorProcessor relevant to the given $expression. * * @param \qtism\data\expressions\Expression $expression The Operator object you want to get the processor. * @param \qtism\runtime\expressions\operators\OperandsCollection $operands The operands to be involved in the Operator object. * @return \qtism\runtime\expressions\operators\OperatorProcessor An OperatorProcessor object ready to process $expression. * @throws \qtism\runtime\expressions\operators\OperatorProcessingException If the $operands count is not compliant with the Operator object to be processed. * @throws \InvalidArgumentException If $expression is not an Operator object. * @throws \RuntimeException If no relevant OperatorProcessor is found for the given $expression. */ public function createProcessor(QtiComponent $expression, OperandsCollection $operands = null) { if ($expression instanceof Operator) { if ($expression instanceof CustomOperator) { // QTI custom operator. Try to load an autoloaded class by using // its class attribute value. if ($expression->hasClass() === true) { $className = Utils::customOperatorClassToPhpClass($expression->getClass()); if (class_exists($className) === true) { return new $className($expression, $operands); } else { $msg = "No custom operator implementation found for class '" . $expression->getClass() . "'."; throw new RuntimeException($msg); } } else { $msg = "Only custom operators with a 'class' attribute value can be processed."; throw new RuntimeException($msg); } } else { // QTI built-in operator. $qtiClassName = ucfirst($expression->getQtiClassName()); $nsPackage = 'qtism\\runtime\\expressions\\operators\\'; $className = $nsPackage . $qtiClassName . 'Processor'; if (class_exists($className)) { if (is_null($operands) === true) { $operands = new OperandsCollection(); } return new $className($expression, $operands); } else { $msg = "No dedicated OperatorProcessor class found for QTI operator '{$qtiClassName}'."; throw new RuntimeException($msg); } } } else { $msg = "The OperatorProcessorFactory only accepts to create processors for Operator objects."; throw new InvalidArgumentException($msg); } }
/** * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::marshallChildrenKnown() */ protected function marshallChildrenKnown(QtiComponent $component, array $elements) { $element = self::getDOMCradle()->createElement($component->getQtiClassName()); foreach ($elements as $elt) { $element->appendChild($elt); } if ($component instanceof CustomOperator) { if ($component->hasClass() === true) { self::setDOMElementAttribute($element, 'class', $component->getClass()); } if ($component->hasDefinition() === true) { self::setDOMElementAttribute($element, 'definition', $component->getDefinition()); } // Now, we have to extract the LAX content of the custom operator and put it into // what we are putting out. (It is possible to have no LAX content at all, it is not mandatory). $xml = $component->getXml(); $operatorElt = $xml->documentElement->cloneNode(true); $qtiOperatorElts = self::getChildElementsByTagName($operatorElt, array_merge(self::getOperators(), self::getExpressions())); foreach ($qtiOperatorElts as $qtiOperatorElt) { $operatorElt->removeChild($qtiOperatorElt); } Utils::importChildNodes($operatorElt, $element); Utils::importAttributes($operatorElt, $element); } return $element; }