<?php
namespace EADPlataforma\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Validator\Constraints as Assert;
use EADPlataforma\Validator\Constraints as EADAssert;
use EADPlataforma\Enum\ExamEnum;
use EADPlataforma\Enum\QuestionEnum;
use EADPlataforma\Util\StringUtil;
use \DateTime;
/**
* Exam
*
* @ORM\Table(name="exam", indexes={
* @ORM\Index(name="fk_exam_lesson_id", columns={"lesson_id"}),
* @ORM\Index(name="fk_exam_lesson_module_id", columns={"lesson_module_id"}),
* @ORM\Index(name="fk_exam_course_id", columns={"course_id"}),
* @ORM\Index(name="fk_exam_user_delete_id", columns={"user_delete_id"})
* })
*
* @ORM\Entity(repositoryClass="EADPlataforma\Repository\ExamRepository")
*/
class Exam
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @Assert\NotBlank(
* message = "Deleted not informed"
* )
*
* @Assert\Choice(
* choices = {
* ExamEnum::ITEM_NO_DELETED,
* ExamEnum::ITEM_ON_TRASH,
* ExamEnum::ITEM_DELETED
* },
* message = "Delete Option Invalid"
* )
*
* @var int
*
* @ORM\Column(name="deleted", type="integer", nullable=false, options={"default"="0"})
*/
private $deleted = ExamEnum::ITEM_NO_DELETED;
/**
* @Assert\Length(
* min = 0,
* max = 120
* )
*
* @var string|null
*
* @ORM\Column(name="title", type="string", length=125, nullable=true)
*/
private $title;
/**
* @Assert\NotBlank(
* message = "Type not informed"
* )
*
* @Assert\Choice(
* choices = { ExamEnum::COURSE, ExamEnum::MODULE, ExamEnum::LESSON, ExamEnum::QUIZ },
* message = "Type Invalid"
* )
*
* @var int
*
* @ORM\Column(name="type", type="integer", nullable=false, options={"default"="1"})
*/
private $type = ExamEnum::COURSE;
/**
* @Assert\NotBlank(
* message = "Status not informed"
* )
*
* @Assert\Choice(
* choices = { ExamEnum::DRAFT, ExamEnum::PUBLISHED },
* message = "Status Invalid"
* )
*
* @var int
*
* @ORM\Column(name="status", type="integer", nullable=false, options={"default"="0"})
*/
private $status = ExamEnum::DRAFT;
/**
* @Assert\NotBlank(
* message = "Requirement not informed"
* )
*
* @Assert\Choice(
* choices = { ExamEnum::NO, ExamEnum::YES },
* message = "Requirement Invalid"
* )
*
* @var int
*
* @ORM\Column(name="requirement", type="integer", nullable=false, options={"default"="0"})
*/
private $requirement = ExamEnum::NO;
/**
* @Assert\NotBlank(
* message = "Question order not informed"
* )
*
* @Assert\Choice(
* choices = { ExamEnum::SEQUENTIAL, ExamEnum::RANDOM },
* message = "Question order Invalid"
* )
*
* @var int
*
* @ORM\Column(name="question_order", type="integer", nullable=false, options={"default"="0"})
*/
private $questionOrder = ExamEnum::SEQUENTIAL;
/**
* @Assert\NotBlank(
* message = "Question number not informed"
* )
*
* @Assert\GreaterThan(
* value = 0,
* message = "Question number not informed"
* )
*
* @Assert\EqualTo(
* value = 1,
* groups = "lessQuestion",
* message = "The number of questions is less than the number informed!"
* )
*
* @var int
*
* @ORM\Column(name="question_number", type="integer", nullable=false)
*/
private $questionNumber;
/**
* @Assert\NotBlank(
* message = "Exame average not informed"
* )
*
* @Assert\GreaterThan(
* value = 0,
* message = "Exame average Invalid"
* )
*
* @Assert\LessThanOrEqual(
* value = 10,
* message = "Exame average Invalid"
* )
*
* @var int
*
* @ORM\Column(name="exam_average", type="decimal", precision=10, scale=2, nullable=false, options={"default"="7"})
*/
private $examAverage = '7';
/**
* @Assert\NotBlank(
* message = "Exame weight not informed"
* )
*
* @Assert\GreaterThanOrEqual(
* value = 0,
* message = "Exame weight Invalid"
* )
*
* @Assert\LessThanOrEqual(
* value = 10,
* message = "Exame weight Invalid"
* )
*
* @var int
*
* @ORM\Column(name="exam_weight", type="integer", nullable=false, options={"default"="0"})
*/
private $examWeight = '0';
/**
* @Assert\NotBlank(
* message = "Type Release not informed"
* )
*
* @Assert\Choice(
* choices = { ExamEnum::RELEASED, ExamEnum::FIXED_DATE, ExamEnum::FLEXIBLE_PERIOD },
* message = "Type Release Invalid"
* )
*
* @var int
*
* @ORM\Column(name="type_release", type="integer", nullable=false, options={"default"="1"})
*/
private $typeRelease = ExamEnum::RELEASED;
/**
* @Assert\NotBlank(
* message = "Period start not informed"
* )
*
* @Assert\GreaterThan(
* value = 0,
* groups = "typeReleaseFlexible",
* message = "Period start Invalid"
* )
*
* @var int
*
* @ORM\Column(name="period_start", type="integer", nullable=false, options={"default"="0"})
*/
private $periodStart = '0';
/**
* @Assert\NotBlank(
* message = "Period end not informed"
* )
*
* @var int
*
* @ORM\Column(name="period_end", type="integer", nullable=false, options={"default"="0"})
*/
private $periodEnd = '0';
/**
* @Assert\NotBlank(
* groups = "typeReleaseFixedDate",
* message = "Date Start not informed"
* )
*
* @EADAssert\DateTimeEAD(
* message = "Date Start Invalid"
* )
*
* @var \DateTime|null
*
* @ORM\Column(name="date_start", type="datetime", nullable=true)
*/
private $dateStart;
/**
* @Assert\NotBlank(
* groups = "notQuiz",
* message = "Exam Time not informed"
* )
*
* @Assert\NotEqualTo(
* value = "00:00:00",
* groups = "notQuiz",
* message = "Exam Time not informed"
* )
*
* @EADAssert\TimeEAD(
* message = "Exam Time Invalid"
* )
*
* @var Time|null
*
* @ORM\Column(name="exam_time", type="string", length=10, nullable=true)
*/
private $examTime;
/**
* @Assert\NotBlank(
* message = "Attempts not informed"
* )
*
* @Assert\Choice(
* choices = { ExamEnum::NO, ExamEnum::YES },
* message = "Attempts Invalid"
* )
*
* @var int
*
* @ORM\Column(name="attempts", type="integer", nullable=false, options={"default"="0"})
*/
private $attempts = ExamEnum::NO;
/**
* @Assert\NotBlank(
* message = "Attempts number not informed"
* )
*
* @Assert\GreaterThan(
* value = 0,
* message = "Attempts number Invalid"
* )
*
* @var int
*
* @ORM\Column(name="attempts_number", type="integer", nullable=false, options={"default"="1"})
*/
private $attemptsNumber = '1';
/**
* @Assert\NotBlank(
* message = "Attempts auto release not informed"
* )
*
* @Assert\Choice(
* choices = { ExamEnum::NO, ExamEnum::YES },
* message = "Attempts Auto Release Invalid"
* )
*
* @var int
*
* @ORM\Column(name="attempts_auto_release", type="integer", nullable=false, options={"default"="1"})
*/
private $attemptsAutoRelease = ExamEnum::YES;
/**
* @Assert\NotBlank(
* message = "Attempts type release not informed"
* )
*
* @Assert\Choice(
* choices = { ExamEnum::DAYS, ExamEnum::HOURS },
* message = "Attempts type Release Invalid"
* )
*
* @var int
*
* @ORM\Column(name="attempts_type_release", type="integer", nullable=false, options={"default"="1"})
*/
private $attemptsTypeRelease = ExamEnum::DAYS;
/**
* @Assert\NotBlank(
* groups = "attemptsTypeReleaseHours",
* message = "Attempts Time not informed"
* )
*
* @Assert\NotEqualTo(
* value = "00:00:00",
* groups = "attemptsTypeReleaseHours",
* message = "Attempts Time not informed"
* )
*
* @EADAssert\TimeEAD(
* message = "Attempts Time Invalid"
* )
*
* @var Time|null
*
* @ORM\Column(name="attempts_time", type="string", length=10, nullable=true)
*/
private $attemptsTime;
/**
* @Assert\NotBlank(
* groups = "attemptsTypeReleaseDays",
* message = "Attempts Period not informed"
* )
*
* @Assert\GreaterThan(
* value = 0,
* groups = "attemptsTypeReleaseDays",
* message = "Attempts Period Invalid"
* )
*
* @var int|null
*
* @ORM\Column(name="attempts_period", type="integer", nullable=true)
*/
private $attemptsPeriod;
/**
* @Assert\NotBlank(
* message = "Show template not informed"
* )
*
* @Assert\Choice(
* choices = { ExamEnum::NO, ExamEnum::YES },
* message = "Show Template Invalid"
* )
*
* @var int
*
* @ORM\Column(name="show_template", type="integer", nullable=false, options={"default"="0"})
*/
private $showTemplate = ExamEnum::NO;
/**
* @Assert\NotBlank(
* message = "Auto Correct not informed"
* )
*
* @Assert\Choice(
* choices = { ExamEnum::NO, ExamEnum::YES },
* message = "Auto Correct Invalid"
* )
*
* @var int
*
* @ORM\Column(name="auto_correct_text_question", type="integer", nullable=false, options={"default"="0"})
*/
private $autoCorrectTextQuestion = ExamEnum::NO;
/**
* @var string|null
*
* @ORM\Column(name="note", type="text", length=0, nullable=true)
*/
private $note;
/**
* @EADAssert\DateTimeEAD(
* message = "Date Last Notify Invalid"
* )
*
* @var \DateTime|null
*
* @ORM\Column(name="date_last_notify", type="datetime", nullable=true)
*/
private $dateLastNotify;
/**
* @Assert\NotBlank(
* message = "Course not informed"
* )
*
* @Assert\Valid
*
* @var \Course
*
* @ORM\ManyToOne(targetEntity="Course")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="course_id", referencedColumnName="id", nullable=false)
* })
*/
private $course;
/**
* @Assert\NotBlank(
* groups = "lessonModule",
* message = "Lesson Module not informed"
* )
*
* @Assert\Valid
*
* @var \LessonModule
*
* @ORM\ManyToOne(targetEntity="LessonModule")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="lesson_module_id", referencedColumnName="id")
* })
*/
private $lessonModule;
/**
* @Assert\NotBlank(
* groups = "lesson",
* message = "Lesson not informed"
* )
*
* @Assert\Valid
*
* @var \Lesson
*
* @ORM\ManyToOne(targetEntity="Lesson")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="lesson_id", referencedColumnName="id")
* })
*/
private $lesson;
/**
* @Assert\Count(
* min = 0,
* groups = "examPublished",
* minMessage = "You must specify at least one question",
* )
*
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="Question", inversedBy="exam")
* @ORM\JoinTable(name="exam_x_question",
* joinColumns={
* @ORM\JoinColumn(name="exam_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="question_id", referencedColumnName="id")
* }
* )
*/
private $question;
/**
* @Assert\Valid
*
* @var \EADPlataforma\Entity\User
*
* @ORM\ManyToOne(targetEntity="User")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="user_delete_id", referencedColumnName="id", nullable=true)
* })
*/
private $userDelete;
/**
* @Assert\Choice(
* choices = {
* ExamEnum::INDIVIDUAL,
* ExamEnum::CASCADE
* },
* message = "Type Delete Invalid"
* )
*
* @var int
*
* @ORM\Column(name="type_delete", type="integer", nullable=true)
*/
private $typeDelete;
/**
* @EADAssert\DateTimeEAD(
* message = "Date Delete Invalid"
* )
*
* @var \DateTime|null
*
* @ORM\Column(name="date_delete", type="datetime", nullable=true)
*/
private $dateDelete;
/**
*
* @var int
*
* @ORM\Column(name="control_time", type="integer", nullable=false, options={"default"="0"})
*/
private $controlTime = ExamEnum::NO;
/**
* Constructor
*/
public function __construct()
{
$this->question = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return StringUtil::fromUnicode(StringUtil::encodeStringStatic($this->title));
}
public function setTitle(?string $title): self
{
$this->title = StringUtil::toUnicode($title);
return $this;
}
public function getType($string = false)
{
if($string){
return $this->stringType($this->type);
}
return $this->type;
}
public function setType(int $type): self
{
$this->type = $type;
return $this;
}
public function getStatus(): ?int
{
return $this->status;
}
public function setStatus(int $status): self
{
$this->status = $status;
return $this;
}
public function getRequirement(): ?int
{
return $this->requirement;
}
public function setRequirement(int $requirement): self
{
$this->requirement = $requirement;
return $this;
}
public function getQuestionOrder(): ?int
{
return $this->questionOrder;
}
public function setQuestionOrder(int $questionOrder): self
{
$this->questionOrder = $questionOrder;
return $this;
}
public function getQuestionNumber(): ?int
{
return $this->questionNumber;
}
public function setQuestionNumber(int $questionNumber): self
{
$this->questionNumber = $questionNumber;
return $this;
}
public function getExamAverage()
{
return (float)$this->examAverage;
}
public function setExamAverage($examAverage): self
{
$this->examAverage = (float)$examAverage;
return $this;
}
public function getExamWeight(): ?int
{
return $this->examWeight;
}
public function setExamWeight(int $examWeight): self
{
$this->examWeight = $examWeight;
return $this;
}
public function getTypeRelease(): ?int
{
return $this->typeRelease;
}
public function setTypeRelease(int $typeRelease): self
{
$this->typeRelease = $typeRelease;
return $this;
}
public function getControlTime(): ?int
{
return $this->controlTime;
}
public function setControlTime(int $controlTime): self
{
$this->controlTime = $controlTime;
return $this;
}
public function getPeriodStart(): ?int
{
return $this->periodStart;
}
public function setPeriodStart(int $periodStart): self
{
$this->periodStart = $periodStart;
return $this;
}
public function getPeriodEnd(): ?int
{
return $this->periodEnd;
}
public function setPeriodEnd(int $periodEnd): self
{
$this->periodEnd = $periodEnd;
return $this;
}
public function getDateStart($dateFormat = 'Y-m-d H:i:s')
{
if($this->dateStart){
return $this->dateStart->format($dateFormat);
}
return $this->dateStart;
}
public function setDateStart($dateStart): self
{
if(!empty($dateStart)){
$dateStart = DateTime::createFromFormat('Y-m-d H:i:s', $dateStart);
}else{
$dateStart = null;
}
$this->dateStart = $dateStart;
return $this;
}
public function getExamTime(): ?string
{
return $this->examTime;
}
public function setExamTime(?string $examTime): self
{
$this->examTime = $examTime;
return $this;
}
public function getAttempts(): ?int
{
return $this->attempts;
}
public function setAttempts(int $attempts): self
{
$this->attempts = $attempts;
return $this;
}
public function getAttemptsNumber(): ?int
{
return $this->attemptsNumber;
}
public function setAttemptsNumber(int $attemptsNumber): self
{
$this->attemptsNumber = $attemptsNumber;
return $this;
}
public function getAttemptsAutoRelease(): ?int
{
return $this->attemptsAutoRelease;
}
public function setAttemptsAutoRelease(int $attemptsAutoRelease): self
{
$this->attemptsAutoRelease = $attemptsAutoRelease;
return $this;
}
public function getAttemptsTypeRelease(): ?int
{
return $this->attemptsTypeRelease;
}
public function setAttemptsTypeRelease(int $attemptsTypeRelease): self
{
$this->attemptsTypeRelease = $attemptsTypeRelease;
return $this;
}
public function getAttemptsTime(): ?string
{
return $this->attemptsTime;
}
public function setAttemptsTime(?string $attemptsTime): self
{
$this->attemptsTime = $attemptsTime;
return $this;
}
public function getAttemptsPeriod(): ?int
{
return $this->attemptsPeriod;
}
public function setAttemptsPeriod(?int $attemptsPeriod): self
{
$this->attemptsPeriod = $attemptsPeriod;
return $this;
}
public function getShowTemplate(): ?int
{
return $this->showTemplate;
}
public function setShowTemplate(int $showTemplate): self
{
$this->showTemplate = $showTemplate;
return $this;
}
public function getAutoCorrectTextQuestion(): ?int
{
return $this->autoCorrectTextQuestion;
}
public function setAutoCorrectTextQuestion(int $autoCorrectTextQuestion): self
{
$this->autoCorrectTextQuestion = $autoCorrectTextQuestion;
return $this;
}
public function getNote(): ?string
{
return StringUtil::fromUnicode(StringUtil::encodeStringStatic($this->note));
}
public function setNote(?string $note): self
{
$this->note = StringUtil::toUnicode($note);
return $this;
}
public function getDateLastNotify($dateFormat = 'Y-m-d H:i:s')
{
if($this->dateLastNotify){
return $this->dateLastNotify->format($dateFormat);
}
return $this->dateLastNotify;
}
public function setDateLastNotify($dateLastNotify): self
{
if($dateLastNotify){
$dateLastNotify = DateTime::createFromFormat('Y-m-d H:i:s', $dateLastNotify);
}
$this->dateLastNotify = $dateLastNotify;
return $this;
}
public function getCourse(): ?Course
{
return $this->course;
}
public function setCourse(?Course $course): self
{
$this->course = $course;
return $this;
}
public function getLessonModule(): ?LessonModule
{
return $this->lessonModule;
}
public function setLessonModule(?LessonModule $lessonModule): self
{
$this->lessonModule = $lessonModule;
return $this;
}
public function getLesson(): ?Lesson
{
return $this->lesson;
}
public function setLesson(?Lesson $lesson): self
{
$this->lesson = $lesson;
return $this;
}
public function getUserDelete(): ?User
{
return $this->userDelete;
}
public function setUserDelete(?User $userDelete): self
{
$this->userDelete = $userDelete;
return $this;
}
public function getDateDelete($dateFormat = 'Y-m-d H:i:s')
{
if($this->dateDelete){
return $this->dateDelete->format($dateFormat);
}
return $this->dateDelete;
}
public function setDateDelete($dateDelete): self
{
if(!empty($dateDelete)){
$dateDelete = DateTime::createFromFormat('Y-m-d H:i:s', $dateDelete);
}
$this->dateDelete = $dateDelete;
return $this;
}
/**
* @return Collection|Question[]
*/
public function getQuestion(): Collection
{
return $this->question;
}
public function addQuestion(Question $question): self
{
if (!$this->question->contains($question)) {
$this->question[] = $question;
}
return $this;
}
public function getLiveQuestion(): array
{
$questions = [];
foreach ($this->question as $key => $question) {
if($question->isLive()){
$questions[] = $question;
}
}
return $questions;
}
public function getQuestionNumberReal(): int
{
$questionNumber = $this->getQuestionNumber();
$questionNumberReal = count($this->getLiveQuestion());
if($questionNumber > $questionNumberReal){
$questionNumber = $questionNumberReal;
}
if($this->getQuestionOrder() == ExamEnum::SEQUENTIAL){
$questionNumber = $questionNumberReal;
}
return $questionNumber;
}
public function removeAllQuestion(): self
{
foreach ($this->question as $key => $question) {
$this->question->removeElement($question);
}
return $this;
}
public function removeQuestion(Question $question): self
{
if ($this->question->contains($question)) {
$this->question->removeElement($question);
}
return $this;
}
public function individual(): self
{
$this->typeDelete = ExamEnum::INDIVIDUAL;
return $this;
}
public function cascade(): self
{
$this->typeDelete = ExamEnum::CASCADE;
return $this;
}
public function isOnTrash(): bool
{
return ($this->deleted == ExamEnum::ITEM_ON_TRASH);
}
public function isDeleted(): bool
{
return ($this->deleted == ExamEnum::ITEM_DELETED);
}
public function restore(): self
{
$this->deleted = ExamEnum::ITEM_NO_DELETED;
return $this;
}
public function trash(): self
{
$this->deleted = ExamEnum::ITEM_ON_TRASH;
return $this;
}
public function delete(): self
{
$this->deleted = ExamEnum::ITEM_DELETED;
return $this;
}
public function stringType($type){
$string = '';
switch ($type) {
case ExamEnum::COURSE:
$string = 'Course';
break;
case ExamEnum::MODULE:
$string = 'Module';
break;
case ExamEnum::LESSON:
$string = 'Lesson';
break;
case ExamEnum::QUIZ:
$string = 'Quiz';
break;
}
return $string;
}
public function getQuestionsArray(?bool $onlyQuestionLive = false): ?array
{
$arrQuestion = [];
foreach ($this->question as $key => $question) {
if($question->isLive() || !$onlyQuestionLive){
if(
$this->type != ExamEnum::QUIZ ||
$question->getType() == QuestionEnum::ALTERNATIVE
){
$arrOption = [];
foreach ($question->getOption() as $key => $option) {
if($option->isLive() || !$onlyQuestionLive){
$arrOption[] = (object)[
"id" => $option->getId(),
"option" => html_entity_decode($option->getOption()),
];
}
}
$arrQuestion[] = (object)[
"id" => $question->getId(),
"order" => $question->getOrder(),
"question" => $question->getQuestion(),
"type" => $question->getType(),
"note" => $question->getNote(),
"libraryId" => (
$question->getLibrary() ?
$question->getLibrary()->getId() :
null
),
"options" => $arrOption,
];
}
}
}
if(!empty($arrQuestion)){
usort($arrQuestion, function($a, $b) {return $a->order > $b->order;});
}
return $arrQuestion;
}
public function toReturn(bool $questions = false, bool $onlyQuestionLive = false){
$arrQuestion = [];
if($questions){
$arrQuestion = $this->getQuestionsArray($onlyQuestionLive);
}
$data = [
"id" => $this->id,
"deleted" => $this->deleted,
"title" => $this->getTitle(),
"type" => $this->type,
"status" => $this->status,
"requirement" => $this->requirement,
"questionOrder" => $this->questionOrder,
"questionNumber" => $this->questionNumber,
"examAverage" => $this->examAverage,
"examWeight" => $this->examWeight,
"typeRelease" => $this->typeRelease,
"controlTime" => $this->controlTime,
"periodStart" => $this->periodStart,
"periodEnd" => $this->periodEnd,
"dateStart" => $this->getDateStart(),
"examTime" => $this->getExamTime(),
"attempts" => $this->attempts,
"attemptsNumber" => $this->attemptsNumber,
"attemptsAutoRelease" => $this->attemptsAutoRelease,
"attemptsTypeRelease" => $this->attemptsTypeRelease,
"attemptsTime" => $this->getAttemptsTime(),
"attemptsPeriod" => $this->attemptsPeriod,
"showTemplate" => $this->showTemplate,
"autoCorrectTextQuestion" => $this->autoCorrectTextQuestion,
"note" => $this->getNote(),
"dateLastNotify" => $this->getDateLastNotify(),
"course" => ( $this->course ? $this->course->getId() : null ),
"lessonModule" => ( $this->lessonModule ? $this->lessonModule->getId() : null ),
"lesson" => ( $this->lesson ? $this->lesson->getId() : null ),
"userDelete" => ( $this->userDelete ? $this->userDelete->getId() : null ),
"typeDelete" => $this->typeDelete,
"dateDelete" => $this->getDateDelete()
];
if($questions){
$data["question"] = $arrQuestion;
}
return $data;
}
}