<?php
namespace App\Entity;
use App\Entity\Traits\Timestampable;
use App\Repository\StudentActivityAttemptRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
// Une tentative d'un élève sur une Activity. `attemptNumber` s'incrémente à
// chaque nouvelle tentative (voir Activity::maxAttempts pour la limite
// éventuelle). `score`/`maxScore`/`success` sont calculés côté serveur à la
// soumission (voir StudentAnswer pour le détail par question).
#[ORM\HasLifecycleCallbacks]
#[ORM\Entity(repositoryClass: StudentActivityAttemptRepository::class)]
class StudentActivityAttempt
{
use Timestampable;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
private ?Student $student = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
private ?Activity $activity = null;
#[ORM\Column]
private int $attemptNumber = 1;
#[ORM\Column(nullable: true)]
private ?float $score = null;
#[ORM\Column(nullable: true)]
private ?float $maxScore = null;
#[ORM\Column(nullable: true)]
private ?bool $success = null;
// true = soumise automatiquement par le mobile suite à un dépassement de
// temps limite (Activity::timeLimitSeconds ou Capsule::timeLimitSeconds),
// false = soumise volontairement par l'élève. Sert à distinguer les deux
// cas dans le tableau de résultats enseignant.
#[ORM\Column(options: ['default' => false])]
private bool $autoSubmitted = false;
#[ORM\Column(type: 'datetime', nullable: true)]
private ?\DateTimeInterface $startedAt = null;
#[ORM\Column(type: 'datetime', nullable: true)]
private ?\DateTimeInterface $completedAt = null;
#[ORM\OneToMany(mappedBy: 'attempt', targetEntity: StudentAnswer::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
private Collection $answers;
public function __construct()
{
$this->answers = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getStudent(): ?Student
{
return $this->student;
}
public function setStudent(?Student $student): static
{
$this->student = $student;
return $this;
}
public function getActivity(): ?Activity
{
return $this->activity;
}
public function setActivity(?Activity $activity): static
{
$this->activity = $activity;
return $this;
}
public function getAttemptNumber(): int
{
return $this->attemptNumber;
}
public function setAttemptNumber(int $attemptNumber): static
{
$this->attemptNumber = $attemptNumber;
return $this;
}
public function getScore(): ?float
{
return $this->score;
}
public function setScore(?float $score): static
{
$this->score = $score;
return $this;
}
public function getMaxScore(): ?float
{
return $this->maxScore;
}
public function setMaxScore(?float $maxScore): static
{
$this->maxScore = $maxScore;
return $this;
}
public function isSuccess(): ?bool
{
return $this->success;
}
public function setSuccess(?bool $success): static
{
$this->success = $success;
return $this;
}
public function isAutoSubmitted(): bool
{
return $this->autoSubmitted;
}
public function setAutoSubmitted(bool $autoSubmitted): static
{
$this->autoSubmitted = $autoSubmitted;
return $this;
}
public function getStartedAt(): ?\DateTimeInterface
{
return $this->startedAt;
}
public function setStartedAt(?\DateTimeInterface $startedAt): static
{
$this->startedAt = $startedAt;
return $this;
}
public function getCompletedAt(): ?\DateTimeInterface
{
return $this->completedAt;
}
public function setCompletedAt(?\DateTimeInterface $completedAt): static
{
$this->completedAt = $completedAt;
return $this;
}
/** @return Collection<int, StudentAnswer> */
public function getAnswers(): Collection
{
return $this->answers;
}
public function addAnswer(StudentAnswer $answer): static
{
if (!$this->answers->contains($answer)) {
$this->answers->add($answer);
$answer->setAttempt($this);
}
return $this;
}
public function removeAnswer(StudentAnswer $answer): static
{
if ($this->answers->removeElement($answer)) {
if ($answer->getAttempt() === $this) {
$answer->setAttempt(null);
}
}
return $this;
}
}