<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use App\Filter\ElExamAttemptFilter;
use ApiPlatform\Core\Annotation\ApiFilter;
use App\Repository\ElExamAttemptRepository;
use Doctrine\Common\Collections\Collection;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use App\Entity\Interfaces\ContainerMappedInterface;
use Symfony\Component\Serializer\Annotation\Groups;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\BooleanFilter;
/**
* @ApiResource(
* collectionOperations={
* "get"={
* "security"="is_granted('IS_AUTHENTICATED_FULLY')",
* "normalization_context"={"groups"={"ElExamAttempt:Read"}, "skip_null_values"=false}
* },
* "post_start_exam"={
* "route_name"="api_el_exam_attempts_start_exam",
* "method"="POST",
* "security"="is_granted('IS_AUTHENTICATED_FULLY')",
* "denormalization_context"={"groups"={"ElExamAttempt:Start-Exam"}}
* }
* },
* itemOperations={
* "get"={
* "security"="is_granted('IS_CO_ANY_SPE', object)",
* "normalization_context"={"groups"={"ElExamAttempt:Read"}, "skip_null_values"=false}
* },
* "patch_end_exam"={
* "route_name"="api_el_exam_attempts_end_exam",
* "method"="PATCH",
* "security"="is_granted('IS_CO_ANY_SPE', object)",
* "denormalization_context"={"groups"={"ElExamAttempt:End-Exam"}}
* },
* "patch_restart_exam"={
* "route_name"="api_el_exams_restart_exam",
* "method"="PATCH",
* "security"="is_granted('ROLE_OPERATOR') || is_granted('IS_CO_ANY_SPE', object)",
* "denormalization_context"={"groups"={""}}
* },
* "patch_assessment_complete"={
* "route_name"="api_el_exams_assessment_complete",
* "method"="PATCH",
* "security"="is_granted('IS_CO_OPR', object)",
* "denormalization_context"={"groups"={""}}
* },
* "delete"={"security"="is_granted('IS_CO_ANY_SPE', object)"}
* }
* )
* @ApiFilter(SearchFilter::class, properties={"id": "exact", "container.id": "exact", "elExam.elCourseAlways.id": "exact", "elExam.id": "exact", "elExam.elLession.id": "exact", "elExam.elLessionTopic.id": "exact", "elExam.elTask.id": "exact", "elExam.translations.title": "partial", "elExam.examLevel": "exact", "user.id": "exact", "status": "exact", "resultStatus": "exact"})
* @ApiFilter(BooleanFilter::class, properties={"elExam.isConsiderForPass"})
* @ApiFilter(DateFilter::class, properties={"start", "end"})
* @ApiFilter(ElExamAttemptFilter::class, properties={"search": "partial"})
* @ApiFilter(OrderFilter::class, properties={"id", "start", "end", "status"})
* @ORM\Entity(repositoryClass=ElExamAttemptRepository::class)
*/
class ElExamAttempt implements ContainerMappedInterface
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"ElExamAttempt:Read", "User:Me"})
*/
private $id;
/**
* @ORM\Column(type="datetime", nullable=true)
* @Groups({"ElExamAttempt:Read", "User:Me"})
*/
private $start;
/**
* @ORM\Column(type="datetime", nullable=true)
* @Groups({"ElExamAttempt:Read", "User:Me"})
*/
private $end;
/**
* @ORM\Column(type="string", length=16)
* @Groups({"ElExamAttempt:Read", "User:Me"})
*/
private $status;
public const STATUSEXAMATTEMPT_STARTED = "STARTED";
public const STATUSEXAMATTEMPT_COMPLETED = "COMPLETED";
public const STATUSEXAMATTEMPT_EXPIRED = "EXPIRED";
/**
* @ORM\ManyToOne(targetEntity=User::class, inversedBy="elExamAttempts")
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
* @Groups({"ElExamAttempt:Read"})
*/
private $user;
/**
* @ORM\ManyToOne(targetEntity=ElExam::class, inversedBy="elExamAttempts")
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
* @Groups({"ElExamAttempt:Read", "ElExamAttempt:Start-Exam", "User:Me"})
*/
private $elExam;
/**
* @ORM\ManyToOne(targetEntity=Container::class)
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
* @Groups({"ElExamAttempt:Start-Exam"})
*/
private $container;
/**
* @ORM\OneToMany(targetEntity=ElExamAnswer::class, mappedBy="elExamAttempt")
*/
private $elExamAnswers;
/**
* @ORM\Column(type="integer", nullable=true)
* @Groups({"ElExamAttempt:Read", "User:Me", "ElExamAttempt:Current-Question"})
*/
private $currentQuestionId;
/**
* @ORM\Column(type="integer", nullable=true)
* @Groups({"ElExamAttempt:Read", "User:Me"})
*/
private $totalPoint;
/**
* @ORM\Column(type="decimal", precision=10, scale=2, nullable=true)
* @Groups({"ElExamAttempt:Read", "User:Me"})
*/
private $obtainPoint;
/**
* @ORM\Column(type="string", length=16, nullable=true)
* @Groups({"ElExamAttempt:Read", "User:Me"})
*/
private $resultStatus;
public const RESULTSTATUSEXAMATTEMPT_PASS = "PASS";
public const RESULTSTATUSEXAMATTEMPT_FAIL = "FAIL";
/**
* @Groups({"ElExamAttempt:Complete-Bulk"})
*/
private $elExamAttemptIds = [];
/**
* @ORM\Column(type="boolean", nullable=true)
* @Groups({"ElExamAttempt:Read", "User:Me"})
*/
private $isResultSend;
public function __construct()
{
$this->elExamAnswers = new ArrayCollection();
$this->elExamAttemptIds = [];
}
public function getId(): ?int
{
return $this->id;
}
public function getStart(): ?\DateTimeInterface
{
return $this->start;
}
public function setStart(?\DateTimeInterface $start): self
{
$this->start = $start;
return $this;
}
public function getEnd(): ?\DateTimeInterface
{
return $this->end;
}
public function setEnd(?\DateTimeInterface $end): self
{
$this->end = $end;
return $this;
}
public function getStatus(): ?string
{
return $this->status;
}
public function setStatus(string $status): self
{
$this->status = $status;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getElExam(): ?ElExam
{
return $this->elExam;
}
public function setElExam(?ElExam $elExam): self
{
$this->elExam = $elExam;
return $this;
}
public function getContainer(): ?Container
{
return $this->container;
}
public function setContainer(?Container $container): self
{
$this->container = $container;
return $this;
}
/**
* @return Collection|ElExamAnswer[]
*/
public function getElExamAnswers(): Collection
{
return $this->elExamAnswers;
}
public function addElExamAnswer(ElExamAnswer $elExamAnswer): self
{
if (!$this->elExamAnswers->contains($elExamAnswer)) {
$this->elExamAnswers[] = $elExamAnswer;
$elExamAnswer->setElExamAttempt($this);
}
return $this;
}
public function removeElExamAnswer(ElExamAnswer $elExamAnswer): self
{
if ($this->elExamAnswers->removeElement($elExamAnswer)) {
// set the owning side to null (unless already changed)
if ($elExamAnswer->getElExamAttempt() === $this) {
$elExamAnswer->setElExamAttempt(null);
}
}
return $this;
}
/**
* @Groups({"ElExamAttempt:Read", "User:Me"})
*/
public function getRemainingDuration()
{
if ($this->status === self::STATUSEXAMATTEMPT_STARTED) {
if ($this->getElExam()) {
if ($this->getElExam()->getDuration() < 1) {
return -1;
}
$duration = ($this->getElExam()->getDuration() * 60);
$now = new \DateTime();
$passTime = ($now->getTimestamp() - $this->getStart()->getTimestamp());
$remainingTime = ($duration - $passTime);
return ($remainingTime > 0) ? $remainingTime : 0;
}
}
return 0;
}
public function getCurrentQuestionId(): ?int
{
return $this->currentQuestionId;
}
public function setCurrentQuestionId(?int $currentQuestionId): self
{
$this->currentQuestionId = $currentQuestionId;
return $this;
}
public function getTotalPoint(): ?int
{
return $this->totalPoint;
}
public function setTotalPoint(?int $totalPoint): self
{
$this->totalPoint = $totalPoint;
return $this;
}
public function getObtainPoint(): ?string
{
return $this->obtainPoint;
}
public function setObtainPoint(?string $obtainPoint): self
{
$this->obtainPoint = $obtainPoint;
return $this;
}
public function getResultStatus(): ?string
{
return $this->resultStatus;
}
public function setResultStatus(?string $resultStatus): self
{
$this->resultStatus = $resultStatus;
return $this;
}
public function getElExamAttemptIds()
{
return $this->elExamAttemptIds;
}
public function setElExamAttemptIds($elExamAttemptIds)
{
$this->elExamAttemptIds = $elExamAttemptIds;
return $this;
}
public function getIsResultSend(): ?bool
{
return $this->isResultSend;
}
public function setIsResultSend(?bool $isResultSend): self
{
$this->isResultSend = $isResultSend;
return $this;
}
}