Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
namespace App\Service;
use App\Entity\Answer;
use App\Entity\Question;
use App\Repository\AnswerRepository;
use App\Repository\QuestionRepository;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class QuestionService
* @package App\Service
*/
class QuestionService
{
private QuestionRepository $questionRepository;
private AnswerRepository $answerRepository;
public function __construct(QuestionRepository $questionRepository, AnswerRepository $answerRepository)
{
$this->questionRepository = $questionRepository;
$this->answerRepository = $answerRepository;
}
public function generateNextQuestion(string $topic, array $excludeIds = []) : array
{
/** @var Question[] $questions */
$questions = $this->questionRepository->findAllByTopicExcludeIds($topic, $excludeIds);
if (count($questions) === 0) {
throw new NotFoundHttpException('Next question not found!');
}
/** @var Question $target */
$target = $questions[array_rand($questions)];
if ($target->isSingleChoice() || $target->isMultipleChoiceRandomWrongs()) {
if ($target->getAnswers()->count() < 5) {
/** @var Answer[] $additionalAnswers */
$additionalAnswers = $this->answerRepository
->findAllByTopicAndContentType($topic, $target->getContentType(), $target->getId());
if (count($additionalAnswers) === 0) {
throw new NotFoundHttpException('Additional answers not found');
}
for ($i = 0; $i < (6 - $target->getAnswers()->count()); $i++) {
/** @var int $rnd */
$rnd = array_rand($additionalAnswers);
$target->addAnswer($additionalAnswers[$rnd]);
unset($additionalAnswers[$rnd]);
}
$answers = array_map(function ($answer) {
/** @var Answer $answer */
return [
'id' => $answer->getId(),
'label' => $answer->getLabel()
];
}, $target->getAnswers()->getValues());
shuffle($answers);
return [
'id' => $target->getId(),
'type' => $target->getStructureType(),
'label' => $target->getLabel(),
'answers' => $answers

Leon
committed
public function evaluateQuestion(int $questionId, array $answers) : string

Leon
committed
array_walk($answers, function(&$item) {
$item['id'] = intval($item['id']);
});

Leon
committed
/** @var Answer[] $answers */

Leon
committed
$answerIds = array_map(function ($elem) {

Leon
committed
/** @var array $elem */
return $elem['id'];

Leon
committed
}, $answers);
$answerEntities = $this->answerRepository->findAllByIds($answerIds);

Leon
committed

Leon
committed
/** @var Answer $entity */
foreach ($answerEntities as $entity) {
/** @var array $arr */
foreach ($answers as $arr) {
if ($entity->getId() === $arr['id']) {
if ($entity->getQuestion()->getId() !== $questionId) {
if ($arr['checked'] === true) {
return 'wrong'; // An unrelated question which is checked is always wrong
}
} else if ($entity->isCorrect() !== $arr['checked']) {
return 'wrong'; // If related, values must match
}

Leon
committed
break;
}
}
}
return 'correct';