Newer
Older
require_once "Expressions/ResultOfAnswerOfQuestionExpression.php";
require_once "./Customizing/global/plugins/Services/Repository/RepositoryObject/QuestionSetPool/Parser/classes/Exception/ExpressionNotSupportedByQuestion.php";
require_once "./Customizing/global/plugins/Services/Repository/RepositoryObject/QuestionSetPool/Parser/classes/Exception/QuestionNotExist.php";
require_once "./Customizing/global/plugins/Services/Repository/RepositoryObject/QuestionSetPool/Parser/classes/Exception/OperatorNotSupportedByExpression.php";
require_once "./Customizing/global/plugins/Services/Repository/RepositoryObject/QuestionSetPool/Parser/classes/Exception/UnsupportedExpression.php";
require_once "./Customizing/global/plugins/Services/Repository/RepositoryObject/QuestionSetPool/Parser/classes/Exception/UnsupportedOperation.php";
require_once "./Customizing/global/plugins/Services/Repository/RepositoryObject/QuestionSetPool/Parser/classes/Exception/AnswerIndexNotExist.php";
require_once "./Customizing/global/plugins/Services/Repository/RepositoryObject/QuestionSetPool/Parser/classes/Exception/QuestionNotReachable.php";
require_once "./Customizing/global/plugins/Services/Repository/RepositoryObject/QuestionSetPool/Parser/classes/Exception/AnswerValueNotExist.php";
require_once "./Customizing/global/plugins/Services/Repository/RepositoryObject/QuestionSetPool/Parser/classes/Exception/UnableToParseCondition.php";
require_once "./Customizing/global/plugins/Services/Repository/RepositoryObject/QuestionSetPool/Parser/classes/Exception/DuplicateElement.php";
/**
* Class CompositeValidator
*
* Date: 04.12.13
* Time: 14:19
* @author Thomas Joußen <tjoussen@databay.de>
/**
* @var ilParserQuestionProvider
*
* @todo Needs to be abstract or interface
*/
protected $object_loader;
/**
* @param ilParserQuestionProvider $object_loader
* @oaram ilQuestionSetPoolNode $node
* @param array $data
*/
public function __construct($object_loader, $node, $data)
{
$this->object_loader = $object_loader;
$this->node = $node;
$this->data = $data;
}
public function validate(AbstractComposite $composite)
{
if (is_array($composite->nodes) && count($composite->nodes) > 0) {
$this->validate($composite->nodes[0]);
$this->validate($composite->nodes[1]);
$this->validateSubTree($composite);
}
private function validateSubTree(AbstractComposite $composite)
{
if ($composite->nodes[0] instanceof QuestionExpressionInterface &&
$composite->nodes[1] instanceof SolutionExpressionInterface
) {
$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 NumberOfResultExpression && !($question instanceof assClozeTest)) {
$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 OrderingResultExpression &&
($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 DuplicateElement($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 PercentageResultExpression &&
$this->isResultOfAnswerExpression($question_expression) &&
!($question instanceof assFormulaQuestion)
) {
throw new ExpressionNotSupportedByQuestion($answer_expression->getValue(), $question_index . "[" . ($answer_index + 1) . "]");
}
} elseif (
($composite->nodes[0] instanceof AbstractOperation &&
$composite->nodes[1] instanceof ExpressionInterface) ||
($composite->nodes[0] instanceof ExpressionInterface &&
$composite->nodes[1] instanceof AbstractOperation) ||
($composite->nodes[0] instanceof SolutionExpressionInterface)
) {
throw new UnableToParseCondition("");
}
}
/**
* @param int $answer_index
* @param assQuestion|iQuestionCondition $question
* @param ExpressionInterface $answer_expression
* @param int $question_index
*
* @throws AnswerValueNotExist
*/
private function validateClozeTest($answer_index, $question, $answer_expression, $question_index)
{
if ($answer_index !== null) {
$options = $question->getAvailableAnswerOptions($answer_index);
$found = false;
switch ($options->getType()) {
case 0: // text
if (
$answer_expression instanceof StringResultExpression
) {
$found = true;
}
tjoussen
committed
if ($answer_expression instanceof StringResultExpression) {
foreach ($options->getItems(new ilArrayElementShuffler()) as $item) {
if ($item->getAnswertext() == $answer_expression->getText()) {
$found = true;
}
}
} elseif ($answer_expression instanceof NumberOfResultExpression) {
foreach ($options->getItems(new ilArrayElementShuffler()) as $item) {
if ($item->getOrder() == $answer_expression->getNumericValue() - 1) {
$found = true;
}
}
}
break;
case 2: // numeric
if ($answer_expression instanceof NumericResultExpression) {
$found = true;
}
break;
}
if ($answer_expression instanceof EmptyAnswerExpression) {
$found = true;
}
if (!$found && !($answer_expression instanceof PercentageResultExpression)) {
throw new AnswerValueNotExist($question_index, $answer_expression->getValue(), $answer_index + 1);
}
}
}
/**
* @param iQuestionCondition $question
* @param int $question_index
* @param int $answer_index
*
* @throws AnswerIndexNotExist
*/
private function checkIfAnswerIndexOfQuestionExists($question, $question_index, $answer_index)
{
$answer_options = $question->getAvailableAnswerOptions($answer_index);
if ($answer_options == null) {
throw new AnswerIndexNotExist($question_index, $answer_index + 1);
}
}
/**
* @param assQuestion|null $question
* @param int $index
*
* @throws QuestionNotExist
*/
private function checkQuestionExists($question, $index)
{
if ($question == null) {
throw new QuestionNotExist($index);
}
}
/**
* @param ExpressionInterface $expression
*
* @return bool
*/
private function isResultOfAnswerExpression($expression)
{
return $expression instanceof ResultOfAnswerOfQuestionExpression;
}
/**
* @param array $expressions
* @param ExpressionInterface $answer_expression
* @param int $question_index
*
* @throws ExpressionNotSupportedByQuestion
*/
private function checkAnswerExpressionExist($expressions, $answer_expression, $question_index)
{
if (!in_array($answer_expression::$identifier, $expressions)) {
throw new ExpressionNotSupportedByQuestion($answer_expression->getValue(), $question_index);
}
}
/**
* @param array $operators
* @param ExpressionInterface $answer_expression
* @param string $pattern
*
* @throws OperatorNotSupportedByExpression
*/
private function checkOperatorExistForExpression($operators, $answer_expression, $pattern)
{
if (!in_array($pattern, $operators)) {
throw new OperatorNotSupportedByExpression($answer_expression->getValue(), $pattern);
}
}
/**
* @param $question
* @param $index
*
* @throws QuestionNotReachable
*/
private function checkQuestionIsReachable($question, $index)
{
$reachable = false;
foreach ($this->data as $node) {
if ($node["node_index"] > $this->node->getIndex()) {
break;
}
if ($node["question_fi"] == $question->getId()) {
$reachable = true;
break;
}
}
if (!$reachable) {
throw new QuestionNotReachable($index);
}
}