private function validateSubTree(ilAssLacAbstractComposite $composite) { if ($composite->nodes[0] instanceof ilAssLacQuestionExpressionInterface && $composite->nodes[1] instanceof ilAssLacSolutionExpressionInterface) { $question_expression = $composite->nodes[0]; $answer_expression = $composite->nodes[1]; $question_index = $composite->nodes[0]->getQuestionIndex(); $answer_index = null; $question = $this->object_loader->getQuestion($question_index); $this->checkQuestionExists($question, $question_index); //$this->checkQuestionIsReachable($question, $question_index); if ($this->isResultOfAnswerExpression($question_expression)) { $answer_index = $question_expression->getAnswerIndex() - 1; $this->checkIfAnswerIndexOfQuestionExists($question, $question_index, $answer_index); } if ($answer_expression instanceof ilAssLacNumberOfResultExpression) { $this->checkIfAnswerIndexOfQuestionExists($question, $question_index, $answer_expression->getNumericValue() - 1); } $this->checkAnswerExpressionExist($question->getExpressionTypes(), $answer_expression, $question_index); $this->checkOperatorExistForExpression($question->getOperators($answer_expression::$identifier), $answer_expression, $composite::$pattern); if ($answer_expression instanceof ilAssLacOrderingResultExpression && ($question instanceof assOrderingHorizontal || $question instanceof assOrderingQuestion)) { foreach ($answer_expression->getOrdering() as $order) { $count = 0; foreach ($answer_expression->getOrdering() as $element) { if ($element == $order) { $count++; } } if ($count > 1) { throw new ilAssLacDuplicateElement($order); } $this->checkIfAnswerIndexOfQuestionExists($question, $question_index, $order - 1); } } if ($question instanceof assClozeTest) { $this->validateClozeTest($answer_index, $question, $answer_expression, $question_index); } elseif ($answer_expression instanceof ilAssLacPercentageResultExpression && $this->isResultOfAnswerExpression($question_expression) && !$question instanceof assFormulaQuestion) { throw new ilAssLacExpressionNotSupportedByQuestion($answer_expression->getValue(), $question_index . "[" . ($answer_index + 1) . "]"); } } elseif ($composite->nodes[0] instanceof ilAssLacAbstractOperation && $composite->nodes[1] instanceof ilAssLacExpressionInterface || $composite->nodes[0] instanceof ilAssLacExpressionInterface && $composite->nodes[1] instanceof ilAssLacAbstractOperation || $composite->nodes[0] instanceof ilAssLacSolutionExpressionInterface) { throw new ilAssLacUnableToParseCondition(""); } }
/** * @param ilAssLacAbstractComposite $composite * * @return bool */ private function evaluateSubTree(ilAssLacAbstractComposite $composite) { $result = false; if ($composite->nodes[0] instanceof ilAssLacExpressionInterface && $composite->nodes[1] instanceof ilAssLacExpressionInterface) { $question = $this->object_loader->getQuestion($composite->nodes[0]->getQuestionIndex()); $rightNode = $composite->nodes[1]; $index = $this->isInstanceOfAnswerIndexProvidingExpression($composite) ? $composite->nodes[0]->getAnswerIndex() : null; $solutions = $question->getUserQuestionResult($this->activeId, $this->pass); if ($question instanceof assClozeTest) { // @todo for Thomas J.: Move to interface / implement in concrete class (req. for future releases) /** * @var $gap assClozeGap * @var $answer assAnswerCloze */ $result = $solutions->getSolutionForKey($index); $gap = $question->getAvailableAnswerOptions($index - 1); if ($rightNode instanceof ilAssLacStringResultExpression) { if ($gap->getType() == 1) { $answer = $gap->getItem($result['value'] - 1); $solutions->removeByKey($index); $solutions->addKeyValue($index, $answer->getAnswertext()); } } else { if ($rightNode instanceof ilAssLacPercentageResultExpression && $composite->nodes[0] instanceof ilAssLacResultOfAnswerOfQuestionExpression) { /** * @var $answers assAnswerCloze[] */ $answers = $gap->getItems(); $max_points = 0; foreach ($answers as $answer) { if ($max_points < $answer->getPoints()) { $max_points = $answer->getPoints(); } } $item = null; $reached_points = null; // @todo for Thomas J.: Maybe handle identical scoring for every type switch ($gap->getType()) { case CLOZE_TEXT: for ($order = 0; $order < $gap->getItemCount(); $order++) { $answer = $gap->getItem($order); $item_points = $question->getTextgapPoints($answer->getAnswertext(), $result['value'], $answer->getPoints()); if ($item_points > $reached_points) { $reached_points = $item_points; } } break; case CLOZE_NUMERIC: for ($order = 0; $order < $gap->getItemCount(); $order++) { $answer = $gap->getItem($order); $item_points = $question->getNumericgapPoints($answer->getAnswertext(), $result["value"], $answer->getPoints(), $answer->getLowerBound(), $answer->getUpperBound()); if ($item_points > $reached_points) { $reached_points = $item_points; } } break; case CLOZE_SELECT: if ($result['value'] != null) { $answer = $gap->getItem($result['value'] - 1); $reached_points = $answer->getPoints(); } break; } $percentage = 0; if ($max_points != 0 && $reached_points !== null) { $percentage = (int) ($reached_points / $max_points * 100); } $solutions->setReachedPercentage($percentage); } } } if ($question instanceof assFormulaQuestion && $rightNode instanceof ilAssLacPercentageResultExpression && $this->isInstanceOfAnswerIndexProvidingExpression($composite->nodes[0])) { // @todo for Thomas J.: Move to interface / implement in concrete class (req. for future releases) $result = $solutions->getSolutionForKey($index); $answer = $question->getAvailableAnswerOptions($index - 1); $unit = $solutions->getSolutionForKey($index . "_unit"); $key = null; if (is_array($unit)) { $key = $unit['value']; } $max_points = $answer->getPoints(); $points = $answer->getReachedPoints($question->getVariables(), $question->getResults(), $result["value"], $key, $question->getUnitrepository()->getUnits()); $percentage = 0; if ($max_points != 0) { $percentage = (int) ($points / $max_points * 100); } $solutions->setReachedPercentage($percentage); } $result = $rightNode->checkResult($solutions, $composite->getPattern(), $index); } else { switch ($composite->getPattern()) { case "&": $result = $composite->nodes[0] && $composite->nodes[1]; break; case "|": $result = $composite->nodes[0] || $composite->nodes[1]; break; default: $result = false; } } if ($composite->isNegated()) { return !$result; } return $result; }