コード例 #1
0
 /**
  * @dataProvider sequencedIdentifiersProvider
  * 
  * @param string $identifier
  * @param string $expectedPrefix
  * @param string $expectedSequence
  * @param string $expectedVariableName
  */
 public function testSequencedIdentifiers($identifier, $expectedPrefix, $expectedSequence, $expectedVariableName)
 {
     $v = new VariableIdentifier($identifier);
     $this->assertEquals($identifier, $v->getIdentifier());
     $this->assertTrue($v->hasPrefix());
     $this->assertTrue($v->hasSequenceNumber());
     $this->assertEquals($expectedPrefix, $v->getPrefix());
     $this->assertEquals($expectedVariableName, $v->getVariableName());
     $this->assertEquals($expectedSequence, $v->getSequenceNumber());
 }
コード例 #2
0
 /**
  * Set the value of a variable with identifier $offset.
  * 
  * @throws OutOfRangeException If $offset is not a string or an invalid variable identifier.
  * @throws OutOfBoundsException If the variable with identifier $offset cannot be found.
  */
 public function offsetSet($offset, $value)
 {
     if (gettype($offset) !== 'string') {
         $msg = "An AssessmentTestSession object must be addressed by string.";
         throw new OutOfRangeException($msg);
     }
     try {
         $v = new VariableIdentifier($offset);
         if ($v->hasPrefix() === false) {
             // global scope request.
             $data =& $this->getDataPlaceHolder();
             $varName = $v->getVariableName();
             if (isset($data[$varName]) === false) {
                 $msg = "The variable '{$varName}' to be set does not exist in the current context.";
                 throw new OutOfBoundsException($msg);
             }
             $data[$offset]->setValue($value);
             return;
         } else {
             // prefix given.
             // - prefix targets an item ?
             $store = $this->getAssessmentItemSessionStore();
             $items = $this->getAssessmentItemRefs();
             $sequence = $v->hasSequenceNumber() === true ? $v->getSequenceNumber() - 1 : 0;
             $prefix = $v->getPrefix();
             try {
                 if (isset($items[$prefix]) && ($session = $this->getItemSession($items[$prefix], $sequence)) !== false) {
                     $session[$v->getVariableName()] = $value;
                     return;
                 }
             } catch (OutOfBoundsException $e) {
                 // The session could be retrieved, but no such variable into it.
             }
             $msg = "The variable '" . $v->__toString() . "' does not exist in the current context.";
             throw new OutOfBoundsException($msg);
         }
     } catch (InvalidArgumentException $e) {
         // Invalid variable identifier.
         $msg = "AssessmentTestSession object addressed with an invalid identifier '{$offset}'.";
         throw new OutOfRangeException($msg, 0, $e);
     }
 }
コード例 #3
0
ファイル: Route.php プロジェクト: nagyist/qti-sdk
 /**
  * Perform a branching on a TestPart, AssessmentSection or AssessmentItemRef with
  * the given $identifier.
  * 
  * The target will be considered invalid if the following constraints are not fullfilled:
  * 
  * From IMS QTI:
  * In the case of an item or section, the target must refer to an item or section in the same 
  * testPart that has not yet been presented. For testParts, the target must refer to another testPart.
  *
  * @param string $identifier A QTI Identifier to be the target of the branching.
  * @throws \OutOfBoundsException If an error occurs while branching e.g. the $identifier is not referenced in the route or the target is invalid.
  * @throws \OutOfRangeException If $identifier is not a valid branching identifier.
  */
 public function branch($identifier)
 {
     try {
         $identifier = new VariableIdentifier($identifier);
         $id = $identifier->hasPrefix() === false ? $identifier->getVariableName() : $identifier->getPrefix();
         $occurence = $identifier->hasPrefix() === false ? 0 : intval($identifier->getVariableName() - 1);
     } catch (InvalidArgumentException $e) {
         $msg = "The given identifier '{$identifier}' is an invalid branching target.";
         throw new OutOfRangeException($msg);
     }
     // Check for an assessmentItemRef.
     $assessmentItemRefs = $this->getAssessmentItemRefs();
     if (isset($assessmentItemRefs[$id]) === true) {
         $assessmentItemRefMap = $this->getAssessmentItemRefMap();
         $targetRouteItems = $assessmentItemRefMap[$assessmentItemRefs[$id]];
         if ($targetRouteItems[$occurence]->getTestPart() !== $this->current()->getTestPart()) {
             // From IMS QTI:
             // In case of an item or section, the target must refer to an item or section
             // in the same testPart [...]
             $msg = "Branchings to items outside of the current testPart is forbidden by the QTI 2.1 specification.";
             throw new OutOfBoundsException($msg);
         }
         $this->setPosition($this->getRouteItemPosition($targetRouteItems[$occurence]));
         return;
     }
     // Check for an assessmentSection.
     $assessmentSectionIdentifierMap = $this->getAssessmentSectionIdentifierMap();
     if (isset($assessmentSectionIdentifierMap[$id]) === true) {
         if ($assessmentSectionIdentifierMap[$id][0]->getTestPart() !== $this->current()->getTestPart()) {
             // From IMS QTI:
             // In case of an item or section, the target must refer to an item or section
             // in the same testPart [...]
             $msg = "Branchings to assessmentSections outside of the current testPart is forbidden by the QTI 2.1 specification.";
             throw new OutOfBoundsException($msg);
         }
         // We branch to the first RouteItem belonging to the section.
         $this->setPosition($this->getRouteItemPosition($assessmentSectionIdentifierMap[$id][0]));
         return;
     }
     // Check for a testPart.
     $testPartIdentifierMap = $this->getTestPartIdentifierMap();
     if (isset($testPartIdentifierMap[$id]) === true) {
         // We branch to the first RouteItem belonging to the testPart.
         if ($testPartIdentifierMap[$id][0]->getTestPart() === $this->current()->getTestPart()) {
             // From IMS QTI:
             // For testParts, the target must refer to another testPart.
             $msg = "Cannot branch to the same testPart.";
             throw new OutOfBoundsException($msg);
         }
         // We branch to the first RouteItem belonging to the testPart.
         $this->setPosition($this->getRouteItemPosition($testPartIdentifierMap[$id][0]));
         return;
     }
     // No such identifier referenced in the route, cannot branch.
     $msg = "No such identifier '{$id}' found in the route for branching.";
     throw new OutOfBoundsException($msg);
 }
コード例 #4
0
 /**
  * Process the Variable expression.
  *
  * * If the requested variable does not exist, NULL is returned.
  * * In a test context, if the requested weight does not exist, the raw value of the variable is returned.
  *
  * @returns null|mixed The value of the target variable or NULL if the variable does not exist.
  * @throws \qtism\runtime\expressions\ExpressionProcessingException
  */
 public function process()
 {
     $state = $this->getState();
     $variableIdentifier = $this->getExpression()->getIdentifier();
     $weightIdentifier = $this->getExpression()->getWeightIdentifier();
     $variable = $state->getVariable($variableIdentifier);
     if (empty($variable)) {
         return null;
     }
     $variableValue = $state[$variableIdentifier];
     if ($variable->isNull()) {
         return $variableValue;
         // Even if empty string, it is considered by QTI as null.
     }
     // We have a value for this variable, is it weighted?
     if ($state instanceof AssessmentTestSession) {
         try {
             $vIdentifier = new VariableIdentifier($variableIdentifier);
             if ($vIdentifier->hasPrefix() === true && empty($weightIdentifier) === false) {
                 $weight = $state->getWeight($vIdentifier->getPrefix() . '.' . $weightIdentifier);
                 $baseType = $variableValue->getBaseType();
                 $cardinality = $variableValue->getCardinality();
                 // From IMS QTI:
                 // Weights only apply to item variables with base types integer and float.
                 // If the item variable is of any other type the weight is ignored.
                 if (!empty($weight) && ($baseType === BaseType::INTEGER || $baseType === BaseType::FLOAT)) {
                     if ($cardinality === Cardinality::SINGLE) {
                         return new Float($variableValue->getValue() * $weight->getValue());
                     } elseif ($cardinality === Cardinality::MULTIPLE || $cardinality === Cardinality::ORDERED) {
                         // variableValue is an object, the weighting should not
                         // affect the content of the state so a new container is created.
                         $finalValue = $cardinality === Cardinality::MULTIPLE ? new MultipleContainer(BaseType::FLOAT) : new OrderedContainer(BaseType::FLOAT);
                         for ($i = 0; $i < count($variableValue); $i++) {
                             if ($variableValue[$i] !== null) {
                                 $finalValue[] = new Float($variableValue[$i]->getValue() * $weight->getValue());
                             } else {
                                 $finalValue[] = null;
                             }
                         }
                         return $finalValue;
                     }
                 } else {
                     return $variableValue;
                 }
             } else {
                 return $variableValue;
             }
         } catch (InvalidArgumentException $e) {
             // Invalid $variableIdentifier.
             $msg = "Invalid identifier '{$variableIdentifier}' given for variable identifier.";
             throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::NONEXISTENT_VARIABLE, $e);
         }
     } else {
         return $variableValue;
     }
 }