feat: decide when a conditional questionnaire question is shown
This commit is contained in:
1 parent
a84275b40e
commit
d06b647dac
4 files changed
+170
No files matched your search
@@ -19,4 +19,26 @@ readonly class Condition
|
||||
public string|array|int $value,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the controlling question's answer satisfies this condition. An unanswered question
|
||||
* satisfies none: a follow-up stays hidden until there is something to follow up on.
|
||||
*
|
||||
* This says nothing about whether the controlling question is itself shown; that is
|
||||
* Definition::isVisible().
|
||||
*
|
||||
* @param array<string, mixed> $answers keyed by question key
|
||||
*/
|
||||
public function isMet(array $answers): bool
|
||||
{
|
||||
$answer = $answers[$this->question] ?? null;
|
||||
|
||||
return match ($this->operator) {
|
||||
ConditionOperator::EQUALS => $answer === $this->value,
|
||||
ConditionOperator::IN => in_array($answer, $this->value, true),
|
||||
// A rating arrives as an int from the form and from stored JSON alike; anything else
|
||||
// is not a rating.
|
||||
ConditionOperator::LTE => is_int($answer) && $answer <= $this->value,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -40,4 +40,27 @@ readonly class Definition
|
||||
{
|
||||
return $this->getQuestions()[$key] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a question is shown for these answers: it has no show_if, or its condition is met
|
||||
* and the question it depends on is shown in turn. A hidden question's answer counts for
|
||||
* nothing, even if one was given before it was hidden - otherwise a follow-up could stay open
|
||||
* on an answer the respondent can no longer see.
|
||||
*
|
||||
* Terminates because a show_if may only name an earlier question (QuestionnaireCatalog).
|
||||
*
|
||||
* @param array<string, mixed> $answers keyed by question key
|
||||
*/
|
||||
public function isVisible(Question $question, array $answers): bool
|
||||
{
|
||||
if (null === $question->showIf) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$controlling = $this->getQuestion($question->showIf->question);
|
||||
|
||||
return null !== $controlling
|
||||
&& $this->isVisible($controlling, $answers)
|
||||
&& $question->showIf->isMet($answers);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user