public function testLookupOutcomeValue() { $rule = $this->createComponentFromXml(' <lookupOutcomeValue identifier="outcome1"> <baseValue baseType="integer">2</baseValue> </lookupOutcomeValue> '); $outcomeDeclaration = $this->createComponentFromXml(' <outcomeDeclaration identifier="outcome1" cardinality="single" baseType="string"> <matchTable> <matchTableEntry sourceValue="1" targetValue="String1!"/> <matchTableEntry sourceValue="2" targetValue="String2!"/> </matchTable> </outcomeDeclaration> '); $outcomeVariable = OutcomeVariable::createFromDataModel($outcomeDeclaration); $context = new State(array($outcomeVariable)); $engine = new RuleEngine($rule, $context); $this->assertSame(null, $context['outcome1']); $engine->process(); $this->assertEquals('String2!', $context['outcome1']->getValue()); }
/** * Execute the ResponseProcessing according to the current context. * * The following sub-types of ProcessingException may be thrown: * * * RuleProcessingException: If a ResponseRule in the ResponseProcessing produces an error OR if the ExitResponse rule is invoked. In this last case, a specific exception code will be produced to deal with the situation accordingly. * * ExpressionProcessingException: If an Expression within a ResponseRule produces an error. * * ResponseProcessingException: If there is a problem with the response processing template processing bound to the ResponseProcessing. * * @throws \qtism\runtime\common\ProcessingException */ public function process() { // @todo Figure out how to provide a way to the ResponseProcessingEngine to know the folder where to seek for templateLocation, which is a relative URI. $responseProcessing = $this->getComponent(); $template = $responseProcessing->getTemplate(); $templateLocation = $responseProcessing->getTemplateLocation(); if (count($responseProcessing->getResponseRules()) > 0) { // Always prefer the embedded rules. $rules = $responseProcessing->getResponseRules(); } else { $finalTemplateFile = ''; if (empty($template) === false) { // try to locate the template file thanks to the given mapping. $mapping = $this->getTemplateMapping(); if (isset($mapping[$template])) { $finalTemplateFile = $mapping[$template]; } } if (empty($finalTemplateFile) === true && empty($templateLocation) === false) { // The template could not be resolved using the mapping. // Try to use template location. if (@is_readable($templateLocation) === true) { $finalTemplateFile = $templateLocation; } } if (empty($finalTemplateFile) === true) { $msg = "The template file could not be found: template='{$template}', templateLocation='{$templateLocation}'."; throw new ResponseProcessingException($msg, $this, ResponseProcessingException::TEMPLATE_NOT_FOUND); } // Open the file and retrieve the rules. $this->trace("loading response processing template '{$finalTemplateFile}'"); $php = new PhpDocument(); $php->load($finalTemplateFile); $rules = $php->getDocumentComponent()->getResponseRules(); $this->trace(count($rules) . " responseRule(s) extracted from the response processing template"); } try { foreach ($rules as $rule) { $engine = new RuleEngine($rule, $this->getContext()); $engine->process(); $this->trace($rule->getQtiClassName() . ' executed'); } } catch (RuleProcessingException $e) { if ($e->getCode() !== RuleProcessingException::EXIT_RESPONSE) { throw $e; } else { $this->trace('Termination of response processing.'); } } }