Пример #1
0
 /**
  * Process the Member operator.
  *
  * @return boolean Whether the first operand is contained by the second one as a boolean value, or NULL if any of the sub-expressions are NULL.
  * @throws \qtism\runtime\expressions\operators\OperatorProcessingException
  */
 public function process()
 {
     $operands = $this->getOperands();
     if ($operands->containsNull() === true) {
         return null;
     }
     if ($operands->sameBaseType() === false) {
         $msg = "The Member operator only accepts values with the same baseType.";
         throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_BASETYPE);
     }
     $operand1 = $operands[0];
     $operand2 = $operands[1];
     // The first expression must have single cardinality.
     if (CommonUtils::inferCardinality($operand1) !== Cardinality::SINGLE) {
         $msg = "The first operand of the Member operator must have a single cardinality.";
         throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY);
     }
     // The second expression must have multiple or ordered cardinality.
     $cardinality = CommonUtils::inferCardinality($operand2);
     if ($cardinality !== Cardinality::MULTIPLE && $cardinality !== Cardinality::ORDERED) {
         $msg = "The second operand of the Member operator must have a multiple or ordered cardinality.";
         throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY);
     }
     return new Boolean($operand2->contains($operand1));
 }
Пример #2
0
 /**
  * Process the Delete operator.
  *
  * @return \qtism\common\collections\Container A new container derived from the second sub-expression with all instances of the first sub-expression removed, or NULL if either sub-expression is considered to be NULL.
  * @throws \qtism\runtime\expressions\operators\OperatorProcessingException
  */
 public function process()
 {
     $operands = $this->getOperands();
     if ($operands->containsNull() === true) {
         return null;
     }
     if ($operands->sameBaseType() === false) {
         $msg = "The Delete operator only accepts operands with the same baseType.";
         throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_BASETYPE);
     }
     $operand1 = $operands[0];
     if (RuntimeUtils::inferCardinality($operand1) !== Cardinality::SINGLE) {
         $msg = "The first operand of the Delete operator must have the single cardinality.";
         throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY);
     }
     $operand2 = $operands[1];
     $cardinality = RuntimeUtils::inferCardinality($operand2);
     if ($cardinality !== Cardinality::MULTIPLE && $cardinality !== Cardinality::ORDERED) {
         $msg = "The second operand of the Delete operator must have a cardinality or multiple or ordered.";
         throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY);
     }
     $returnedBaseType = RuntimeUtils::inferBaseType($operand1);
     $returnValue = $cardinality === Cardinality::MULTIPLE ? new MultipleContainer($returnedBaseType) : new OrderedContainer($returnedBaseType);
     foreach ($operand2 as $value) {
         if ($value === $operand1 || $operand1 instanceof Comparable && $operand1->equals($value) === true) {
             // This is the same value, it will not be included in the returned value.
             continue;
         } else {
             $returnValue[] = $value;
         }
     }
     return $returnValue;
 }
 /**
  * Wether the collection is composed of values with the same cardinality. Please
  * note that:
  * 
  * * If the OperandsCollection is empty, false is returned.
  * * If the OperandsCollection contains a NULL value or a NULL container (empty), false is returned
  * 
  * @return boolean
  */
 public function sameCardinality()
 {
     $operandsCount = count($this);
     if ($operandsCount > 0 && !$this->containsNull()) {
         $refType = RuntimeUtils::inferCardinality($this[0]);
         for ($i = 1; $i < $operandsCount; $i++) {
             if ($refType !== RuntimeUtils::inferCardinality($this[$i])) {
                 return false;
             }
         }
         return true;
     } else {
         return false;
     }
 }
Пример #4
0
 /**
  * @dataProvider inferCardinalityProvider
  */
 public function testInferCardinality($value, $expectedCardinality)
 {
     $this->assertTrue(Utils::inferCardinality($value) === $expectedCardinality);
 }
Пример #5
0
 /**
  * Process the Repeat operator.
  *
  * Note: NULL values are simply ignored. If all sub-expressions are NULL, NULL is
  * returned.
  *
  * @return \qtism\runtime\common\OrderedContainer An ordered container filled sequentially by evaluating each sub-expressions, repeated a 'numberRepeats' of times. NULL is returned if all sub-expressions are NULL or numberRepeats < 1.
  * @throws \qtism\runtime\expressions\operators\OperatorProcessingException
  */
 public function process()
 {
     $operands = $this->getOperands();
     // get the value of numberRepeats
     $expression = $this->getExpression();
     $numberRepeats = $expression->getNumberRepeats();
     if (gettype($numberRepeats) === 'string') {
         // Variable reference found.
         $state = $this->getState();
         $varName = Utils::sanitizeVariableRef($numberRepeats);
         $varValue = $state[$varName];
         if (is_null($varValue) === true) {
             $msg = "The variable with name '{$varName}' could not be resolved.";
             throw new OperatorProcessingException($msg, $this);
         } elseif ($varValue instanceof Integer) {
             $msg = "The variable with name '{$varName}' is not an integer value.";
             throw new OperatorProcessingException($msg, $this);
         }
         $numberRepeats = $varValue->getValue();
     }
     if ($numberRepeats < 1) {
         return null;
     }
     $result = null;
     for ($i = 0; $i < $numberRepeats; $i++) {
         $refType = null;
         foreach ($operands as $operand) {
             // If null, ignore
             if (is_null($operand) || $operand instanceof Container && $operand->isNull()) {
                 continue;
             }
             // Check cardinality.
             if ($operand->getCardinality() !== Cardinality::SINGLE && $operand->getCardinality() !== Cardinality::ORDERED) {
                 $msg = "The Repeat operator only accepts operands with a single or ordered cardinality.";
                 throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY);
             }
             // Check baseType.
             $currentType = RuntimeUtils::inferBaseType($operand);
             if ($refType !== null && $currentType !== $refType) {
                 $msg = "The Repeat operator only accepts operands with the same baseType.";
                 throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_BASETYPE);
             } elseif (is_null($result)) {
                 $refType = $currentType;
                 $result = new OrderedContainer($refType);
             }
             // Okay we are good...
             $operandCardinality = RuntimeUtils::inferCardinality($operand);
             if ($operandCardinality !== Cardinality::ORDERED) {
                 $operand = new OrderedContainer($currentType, array($operand));
             }
             foreach ($operand as $o) {
                 $result[] = $o instanceof QtiDatatype ? clone $o : $o;
             }
         }
     }
     if (isset($result) && $result->isNull() !== true) {
         return $result;
     } else {
         return null;
     }
 }