<?php
namespace App\Entity\Core\Quiz;
use App\Entity\Core\Answer;
use App\Entity\Core\Mathproblem;
use App\Entity\Core\TemplateMathproblem;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use JsonException;
#[ORM\Table('quiz_response')]
#[ORM\Entity(repositoryClass: QuizResponseRepository::class)]
class QuizResponse implements QuizResponseInterface
{
/**
* @var int
*/
#[ORM\Column(name: 'id', type: 'integer')]
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'AUTO')]
private int $id;
/**
* @var QuizUnit
*/
#[ORM\JoinColumn(name: 'quiz_unit', referencedColumnName: 'id', onDelete: 'CASCADE')]
#[ORM\ManyToOne(targetEntity: QuizUnit::class, inversedBy: 'quizResponses')]
private QuizUnit $quizUnit;
/**
* @var Mathproblem
*/
#[ORM\JoinColumn(name: 'mathproblem', referencedColumnName: 'id', onDelete: 'CASCADE')]
#[ORM\ManyToOne(targetEntity: Mathproblem::class)]
private Mathproblem $mathproblem;
#[ORM\Column(name: 'createdAt', type: 'datetime', nullable: true)]
private ?DateTime $createdAt;
/**
* @var Answer|null
*/
#[ORM\JoinColumn(name: 'answer', referencedColumnName: 'id', onDelete: 'RESTRICT')]
#[ORM\ManyToOne(targetEntity: Answer::class)]
private ?Answer $answerChosen;
#[ORM\Column(name: 'answer_text', type: 'text', nullable: true)]
private ?string $answerText;
#[ORM\Column(type: 'array', nullable: true)]
private ?array $shuffledAnswerOrder;
/**
* @var int
*/
#[ORM\Column(name: 'position', type: 'integer')]
private int $position;
/**
* @var bool
*/
#[ORM\Column(name: 'is_valid', type: 'boolean', nullable: true, options: ['default' => true])]
private bool $isValid = true;
/**
* @var DateTime
*/
#[ORM\Column(name: 'archived_at', type: 'datetime', nullable: true)]
private ?DateTime $archivedAt;
/**
* @var int
*/
#[ORM\Column(name: 'bin', type: 'integer', nullable: true)]
private int $bin;
/**
* @var bool
*/
#[ORM\Column(name: 'check_answer_clicked', type: 'boolean', nullable: true, options: ['default' => false])]
private bool $checkAnswerClicked;
/**
* @var DateTime
*/
#[ORM\Column(name: 'start_time', type: 'datetime', options: ['default' => '1970-01-01 00:00:00'])]
private DateTime $startTime;
/**
* @var int
*/
#[ORM\Column(name: 'seconds_delayed', type: 'integer', nullable: false, options: ['default' => 0])]
private int $secondsDelayed = 0;
public function __construct()
{
$this->startTime = new DateTime('1970-01-01 00:00:00');
}
public function getSecondsDelayed(): int
{
return $this->secondsDelayed;
}
/**
* @return $this
*/
public function setSecondsDelayed(int $secondsDelayed): static
{
$this->secondsDelayed = $secondsDelayed;
return $this;
}
public function setStartTime(DateTime $startTime): void
{
$this->startTime = $startTime;
}
public function getStartTime(): DateTime
{
return $this->startTime;
}
public function isCheckAnswerClicked(): bool
{
return $this->checkAnswerClicked;
}
public function setCheckAnswerClicked(bool $checkAnswerClicked): void
{
$this->checkAnswerClicked = $checkAnswerClicked;
}
public function getBin(): int
{
return $this->bin;
}
public function setBin(int $bin): void
{
$this->bin = $bin;
}
public function getId(): int
{
return $this->id;
}
public function getQuizUnit(): QuizUnit
{
return $this->quizUnit;
}
/**
* @return $this
*/
public function setQuizUnit(QuizUnit $quizUnit): static
{
$this->quizUnit = $quizUnit;
return $this;
}
public function getMathproblem(): Mathproblem
{
return $this->mathproblem;
}
/**
* @return $this
*/
public function setMathproblem(Mathproblem $mathproblem): static
{
$this->mathproblem = $mathproblem;
return $this;
}
public function getCreatedAt(): ?DateTime
{
return $this->createdAt;
}
public function setCreatedAt(?DateTime $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getAnswerChosen(): ?Answer
{
return $this->answerChosen;
}
public function getDropdownAnswersChosen(): array
{
$answers = json_decode($this->answerText, true);
if (!is_array($answers)) {
// dropdown answers were stored as a string in "answerText" with '|' as delimiter
$answers = explode('|', $this->answerText);
}
return $answers;
}
/**
* @return $this
*/
public function setAnswerChosen(?Answer $answerChosen): static
{
$this->answerChosen = $answerChosen;
$this->createdAt = new DateTime("now");
return $this;
}
public function getAnswerText(): ?string
{
return $this->answerText;
}
public function setAnswerText(?string $answerText): self
{
$this->answerText = $answerText;
$this->createdAt = new DateTime("now");
return $this;
}
public function getShuffledAnswerOrder(): ?array
{
return $this->shuffledAnswerOrder;
}
public function setShuffledAnswerOrder(?array $shuffledAnswerOrder): void
{
$this->shuffledAnswerOrder = $shuffledAnswerOrder;
}
public function getPosition(): int
{
return $this->position;
}
/**
* @return $this
*/
public function setPosition(int $position): static
{
$this->position = $position;
return $this;
}
public function isValid(): bool
{
return $this->isValid;
}
public function setIsValid(bool $isValid): void
{
$this->isValid = $isValid;
}
public function getArchivedAt(): ?DateTime
{
return $this->archivedAt;
}
public function setArchivedAt(DateTime $archivedAt): void
{
$this->archivedAt = $archivedAt;
}
/**
* @throws JsonException
*/
public function getAnswerIsCorrect(): bool
{
$type = $this->getMathproblem()->getTemplate()->getType();
if ($type === TemplateMathproblem::TYPE_DROPDOWN) {
$answersChosen = $this->getDropdownAnswersChosen();
$correctAnswers = $this->getMathproblem()->getCorrectAnswers();
$subAnswer = null;
$isCorrect = true;
$numberOfCorrect = count($correctAnswers);
for ($i = 0; $i < $numberOfCorrect; $i++) {
$corAnswer = $correctAnswers[$i];
$subAnswer = $answersChosen[$i] ?? $subAnswer;
$isCorrect = strcmp($corAnswer, $subAnswer) === 0 ? $isCorrect : false;
}
return $isCorrect;
}
return $this->getAnswerChosen() && $this->getAnswerChosen()->getIsCorrect();
}
}