Skip to content
Snippets Groups Projects
QuestionService.php 3.54 KiB
Newer Older
<?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(),
    public function evaluateQuestion(int $questionId, array $answers) : string
        array_walk($answers, function(&$item) {
           $item['id'] = intval($item['id']);
        });
        }, $answers);
        $answerEntities = $this->answerRepository->findAllByIds($answerIds);
        /** @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
                    }