Initial survey bundle import
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mummert\SurveyBundle\Service;
|
||||
|
||||
use Mummert\SurveyBundle\Model\SurveyContentModel;
|
||||
use Mummert\SurveyBundle\Model\SurveyModel;
|
||||
use Mummert\SurveyBundle\Model\SurveySubmissionModel;
|
||||
use Mummert\SurveyBundle\Repository\SurveyRepository;
|
||||
use Mummert\SurveyBundle\Repository\SurveyQuestionRepository;
|
||||
|
||||
final class SurveyFlowService
|
||||
{
|
||||
public function __construct(
|
||||
private readonly SurveyEngine $surveyEngine,
|
||||
private readonly SurveyRepository $surveyRepository,
|
||||
private readonly SurveyQuestionRepository $surveyQuestionRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
public function resolveCurrentQuestion(SurveyModel $survey, SurveySubmissionModel $submission): ?SurveyContentModel
|
||||
{
|
||||
if ('1' === (string) $submission->isFinished) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$questions = $this->getOrderedQuestions($survey);
|
||||
$currentQuestionId = (int) $submission->currentQuestion;
|
||||
|
||||
if ($currentQuestionId > 0) {
|
||||
foreach ($questions as $question) {
|
||||
if ((int) $question->id === $currentQuestionId) {
|
||||
return $question;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $questions[0] ?? null;
|
||||
}
|
||||
|
||||
public function determineNextQuestion(SurveyModel $survey, SurveyContentModel $currentQuestion, string $normalizedAnswer): ?SurveyContentModel
|
||||
{
|
||||
$questions = $this->getOrderedQuestions($survey);
|
||||
$configuredJumpTarget = $this->resolveYesNoJumpTarget($currentQuestion, $questions, $normalizedAnswer);
|
||||
|
||||
if ($configuredJumpTarget instanceof SurveyContentModel) {
|
||||
return $configuredJumpTarget;
|
||||
}
|
||||
|
||||
$conditionalTarget = $this->surveyEngine->resolveConditionalTarget($survey, $currentQuestion, $normalizedAnswer);
|
||||
|
||||
if ($conditionalTarget instanceof SurveyContentModel) {
|
||||
return $conditionalTarget;
|
||||
}
|
||||
|
||||
foreach ($questions as $index => $question) {
|
||||
if ((int) $question->id === (int) $currentQuestion->id) {
|
||||
return $questions[$index + 1] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{current:int,total:int,percentage:int}
|
||||
*/
|
||||
public function getProgress(SurveyModel $survey, ?SurveyContentModel $currentQuestion): array
|
||||
{
|
||||
$questions = $this->getOrderedQuestions($survey);
|
||||
$total = max(1, count($questions));
|
||||
$current = 1;
|
||||
|
||||
if ($currentQuestion instanceof SurveyContentModel) {
|
||||
foreach ($questions as $index => $question) {
|
||||
if ((int) $question->id === (int) $currentQuestion->id) {
|
||||
$current = $index + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$current = $total;
|
||||
}
|
||||
|
||||
return [
|
||||
'current' => $current,
|
||||
'total' => $total,
|
||||
'percentage' => (int) round(($current / $total) * 100),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<SurveyContentModel>
|
||||
*/
|
||||
private function getOrderedQuestions(SurveyModel $survey): array
|
||||
{
|
||||
$surveyId = (int) $survey->id;
|
||||
|
||||
if ($this->surveyQuestionRepository->countPublishedBySurvey($surveyId) > 0) {
|
||||
return $this->surveyQuestionRepository->findAllBySurvey($surveyId, true);
|
||||
}
|
||||
|
||||
return $this->surveyQuestionRepository->findAllBySurvey($surveyId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<SurveyContentModel> $questions
|
||||
*/
|
||||
private function resolveYesNoJumpTarget(SurveyContentModel $currentQuestion, array $questions, string $normalizedAnswer): ?SurveyContentModel
|
||||
{
|
||||
if ('yes_no_maybe' !== (string) $currentQuestion->type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$targetId = match ($normalizedAnswer) {
|
||||
'yes' => (int) ($currentQuestion->jumpOnYes ?? 0),
|
||||
'no' => (int) ($currentQuestion->jumpOnNo ?? 0),
|
||||
default => 0,
|
||||
};
|
||||
|
||||
if ($targetId <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($questions as $question) {
|
||||
if ((int) $question->id === $targetId) {
|
||||
return $question;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user