示例#1
0
 /**
  * Set the QTI Data Model Rule object to be processed.
  *
  * @param \qtism\runtime\rules\Rule $rule
  * @throws \InvalidArgumentException If $rule is not compliant with the rule processor implementation.
  */
 public function setRule(Rule $rule)
 {
     $expectedType = $this->getRuleType();
     if (Reflection::isInstanceOf($rule, $expectedType) === true) {
         $this->rule = $rule;
     } else {
         $procClass = get_class($this);
         $givenType = get_class($rule);
         $msg = "The {$procClass} Rule Processor only processes {$expectedType} Rule objects, {$givenType} given.";
         throw new InvalidArgumentException($msg);
     }
 }
示例#2
0
 /**
  * Set the QTI Data Model Expression to be processed.
  *
  * @param \qtism\data\expressions\Expression $expression A QTI Data Model Expression object.
  * @throws \InvalidArgumentException If $expression is not a subclass nor implements the Expression type returned by the getExpressionType method.
  */
 public function setExpression(Expression $expression)
 {
     $expectedType = $this->getExpressionType();
     if (ReflectionUtils::isInstanceOf($expression, $expectedType) === true) {
         $this->expression = $expression;
     } else {
         $procClass = get_class($this);
         $givenType = get_class($expression);
         $msg = "The {$procClass} Expression Processor only processes {$expectedType} Expression objects, {$givenType} given.";
         throw new InvalidArgumentException($msg);
     }
     $this->expression = $expression;
 }
示例#3
0
 /**
  * Process the setOutcomeValue/setTemplateValue rule.
  *
  * A RuleProcessingException will be thrown if:
  *
  * * The variable does not exist.
  * * The requested variable is not an OutcomeVariable/TemplateVariable.
  * * The variable's baseType does not match the baseType of the affected value.
  * * An error occurs while processing the related expression.
  *
  * @throws \qtism\runtime\rules\RuleProcessingException If one of the error described above arise.
  */
 public function process()
 {
     $state = $this->getState();
     $rule = $this->getRule();
     $identifier = $rule->getIdentifier();
     $var = $state->getVariable($identifier);
     if (is_null($var) === true) {
         $msg = "No variable with identifier '{$identifier}' to be set in the current state.";
         throw new RuleProcessingException($msg, $this, RuleProcessingException::NONEXISTENT_VARIABLE);
     } elseif (Reflection::isInstanceOf($var, $this->getVariableType()) === false) {
         $msg = "The variable to set '{$identifier}' is not an instance of '" . $this->getVariableType() . "'.";
         throw new RuleProcessingException($msg, $this, RuleProcessingException::WRONG_VARIABLE_TYPE);
     }
     // Process the expression.
     // Its result will be the value to set to the target variable.
     try {
         $expressionEngine = new ExpressionEngine($rule->getExpression(), $state);
         $val = $expressionEngine->process();
     } catch (ExpressionProcessingException $e) {
         $msg = "An error occured while processing the expression bound with the '" . Reflection::shortClassName($rule) . "' rule.";
         throw new RuleProcessingException($msg, $this, RuleProcessingException::RUNTIME_ERROR, $e);
     }
     // The variable exists, its new value is processed.
     try {
         // juggle a little bit (int -> float, float -> int)
         if ($val !== null && $var->getCardinality() === Cardinality::SINGLE) {
             $baseType = $var->getBaseType();
             if ($baseType === BaseType::INTEGER && $val instanceof Float) {
                 $val = new Integer(intval($val->getValue()));
             } elseif ($baseType === BaseType::FLOAT && $val instanceof Integer) {
                 $val = new Float(floatval($val->getValue()));
             }
         }
         $var->setValue($val);
     } catch (InvalidArgumentException $e) {
         $varBaseType = BaseType::getNameByConstant($var->getBaseType()) === false ? 'noBaseType' : BaseType::getNameByConstant($var->getBaseType());
         $varCardinality = Cardinality::getNameByConstant($var->getCardinality());
         // The affected value does not match the baseType of the variable $var.
         $msg = "Unable to set value {$val} to variable '{$identifier}' (cardinality = {$varCardinality}, baseType = {$varBaseType}).";
         throw new RuleProcessingException($msg, $this, RuleProcessingException::WRONG_VARIABLE_BASETYPE, $e);
     }
 }
 /**
  * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown()
  */
 protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children)
 {
     $expressionElts = self::getChildElementsByTagName($element, Expression::getExpressionClassNames());
     if (count($expressionElts) > 0) {
         $marshaller = $this->getMarshallerFactory()->createMarshaller($expressionElts[0]);
         $expression = $marshaller->unmarshall($expressionElts[0]);
     } elseif (($element->localName == 'responseIf' || $element->localName == 'responseElseIf') && count($expressionElts) == 0) {
         $msg = "A '" . $element->localName . "' must contain an 'expression' element. None found at line " . $element->getLineNo() . "'.";
         throw new UnmarshallingException($msg, $element);
     }
     if ($element->localName == 'responseIf' || $element->localName == 'responseElseIf') {
         $className = 'qtism\\data\\rules\\' . ucfirst($element->localName);
         $class = new ReflectionClass($className);
         $object = Reflection::newInstance($class, array($expression, $children));
     } else {
         $className = 'qtism\\data\\rules\\' . ucfirst($element->localName);
         $class = new ReflectionClass($className);
         $object = Reflection::newInstance($class, array($children));
     }
     return $object;
 }
 protected function instantiateMarshaller(ReflectionClass $class, array $args)
 {
     array_unshift($args, '2.0.0');
     return Reflection::newInstance($class, $args);
 }
示例#6
0
文件: Utils.php 项目: nagyist/qti-sdk
 /**
  * Returns a processing error reporting message in the following format:
  *
  * [ExpressionClassName] My message...
  *
  * @param \qtism\data\expressions\Expression $expression A given expression that failed to be processed.
  * @param string $message A formatted error reporting message.
  * @return string
  */
 public static function errorReporting(Expression $expression, $message)
 {
     $shortClassName = Reflection::shortClassName($expression);
     return "[{$shortClassName}] {$message}";
 }
示例#7
0
 /**
  * @see \qtism\data\storage\xml\marshalling\RecursiveMarshaller::unmarshallChildrenKnown()
  */
 protected function unmarshallChildrenKnown(DOMElement $element, QtiComponentCollection $children)
 {
     // Some exceptions applies on instanciation e.g. the And operator is named
     // AndOperator because of PHP reserved words restriction.
     if ($element->localName === 'and') {
         $className = 'qtism\\data\\expressions\\operators\\AndOperator';
     } elseif ($element->localName === 'or') {
         $className = 'qtism\\data\\expressions\\operators\\OrOperator';
     } else {
         $className = 'qtism\\data\\expressions\\operators\\' . ucfirst($element->localName);
     }
     $class = new ReflectionClass($className);
     $params = array($children);
     if ($element->localName === 'customOperator') {
         // Retrieve XML content as a string.
         $frag = $element->ownerDocument->createDocumentFragment();
         $element = $element->cloneNode(true);
         $frag->appendChild($element);
         $params[] = $frag->ownerDocument->saveXML($frag);
         $component = Reflection::newInstance($class, $params);
         if (($class = self::getDOMElementAttributeAs($element, 'class')) !== null) {
             $component->setClass($class);
         }
         if (($definition = self::getDOMElementAttributeAs($element, 'definition')) !== null) {
             $component->setDefinition($definition);
         }
         return $component;
     } else {
         return Reflection::newInstance($class, $params);
     }
 }
示例#8
0
 public function testNewInstanceWithoutArguments()
 {
     $clazz = new ReflectionClass('\\stdClass');
     $instance = Reflection::newInstance($clazz);
     $this->assertInstanceOf('\\stdClass', $instance);
 }
 /**
  * Create a marshaller for a given QtiComponent or DOMElement object, depending on the current mapping
  * of the MarshallerFactory. If no mapping entry can be found, the factory will perform a ultimate
  * trial in the qtism\\data\\storage\\xml\\marshalling namespace to find the relevant Marshaller object.
  * 
  * The newly created marshaller will be set up with the MarshallerFactory itself as its MarshallerFactory
  * object (yes, we know, this is highly recursive but necessary x)).
  * 
  * @param DOMElement|QtiComponent $object A QtiComponent or DOMElement object you want to get the corresponding Marshaller object.
  * @param array $args An optional array of arguments to be passed to the Marshaller constructor.
  * @throws InvalidArgumentException If $object is not a QtiComponent nor a DOMElement object.
  * @throws RuntimeException If no Marshaller object can be created for the given $object.
  * @return Marshaller The corresponding Marshaller object.
  */
 public function createMarshaller($object, array $args = array())
 {
     if ($object instanceof QtiComponent) {
         $qtiClassName = $object->getQtiClassName();
     } else {
         if ($object instanceof DOMElement) {
             $qtiClassName = $object->localName;
         }
     }
     if (isset($qtiClassName)) {
         try {
             // Look for a mapping entry.
             if ($this->hasMappingEntry($qtiClassName)) {
                 $class = new ReflectionClass($this->getMappingEntry($qtiClassName));
             } else {
                 // Look for default.
                 $className = 'qtism\\data\\storage\\xml\\marshalling\\' . ucfirst($qtiClassName) . 'Marshaller';
                 $class = new ReflectionClass($className);
             }
         } catch (ReflectionException $e) {
             $msg = "No marshaller implementation could be found for component '{$qtiClassName}'.";
             throw new RuntimeException($msg, 0, $e);
         }
         $marshaller = Reflection::newInstance($class, $args);
         $marshaller->setMarshallerFactory($this);
         return $marshaller;
     } else {
         $msg = "The object argument must be a QtiComponent or a DOMElementObject, '" . gettype($object) . "' given.";
         throw new InvalidArgumentException($msg);
     }
 }
 /**
  * @dataProvider shortClassNameProvider
  * @param mixed $expected
  * @param mixed $object
  */
 public function testShortClassName($expected, $object)
 {
     $this->assertSame($expected, Reflection::shortClassName($object));
 }