src/Entity/ElExamQuestion.php line 67

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use Doctrine\ORM\Mapping as ORM;
  4. use App\Entity\ElExamQuestionTranslation;
  5. use ApiPlatform\Core\Annotation\ApiFilter;
  6. use App\Entity\Traits\TimestampableEntity;
  7. use Doctrine\Common\Collections\Collection;
  8. use ApiPlatform\Core\Annotation\ApiResource;
  9. use App\Repository\ElExamQuestionRepository;
  10. use App\Entity\Interfaces\OrderMappedInterface;
  11. use Doctrine\Common\Collections\ArrayCollection;
  12. use App\Entity\Interfaces\ContainerMappedInterface;
  13. use Symfony\Component\Serializer\Annotation\Groups;
  14. use Symfony\Component\Validator\Constraints as Assert;
  15. use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
  16. use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
  17. use Locastic\ApiPlatformTranslationBundle\Model\AbstractTranslatable;
  18. use Locastic\ApiPlatformTranslationBundle\Model\TranslationInterface;
  19. /**
  20.  * @ApiResource(
  21.  *      attributes={"security"="is_granted('ROLE_OPERATOR')", "filters"={"translation.groups"}},
  22.  *      normalizationContext={"groups"={"ElExamQuestion:Read"}, "skip_null_values"=false},
  23.  *      denormalizationContext={"groups"={"ElExamQuestion:Write", "ElExamQuestionTranslationGroup", "ElExamOptionTranslationGroup"}},
  24.  *      collectionOperations={
  25.  *          "get"={
  26.  *              "normalization_context"={"groups"={"ElExamQuestion:Read","ElExamQuestion:With-Answer"}, "skip_null_values"=false},
  27.  *              "security"="is_granted('ROLE_OPERATOR') or is_granted('ROLE_INSTRUCTOR')"
  28.  *          },
  29.  *          "get_public"={
  30.  *              "path"="/el_exam_questions/get-public",
  31.  *              "method"="GET",
  32.  *              "normalization_context"={"groups"={"ElExamQuestion:Read"}, "skip_null_values"=false},
  33.  *              "security"="is_granted('IS_AUTHENTICATED_FULLY')"
  34.  *          },
  35.  *          "get_for_exam_complete"={
  36.  *              "path"="/el_exam_questions/get-for-exam-complete",
  37.  *              "method"="GET",
  38.  *              "normalization_context"={"groups"={"ElExamQuestion:Read", "ElExamQuestion:Exam-Complete"}, "skip_null_values"=false},
  39.  *              "security"="is_granted('IS_AUTHENTICATED_FULLY')"
  40.  *          },
  41.  *          "post"={
  42.  *              "security"="is_granted('ROLE_OPERATOR') or is_granted('ROLE_INSTRUCTOR')"
  43.  *          }
  44.  *      },
  45.  *      itemOperations={
  46.  *          "get"={
  47.  *              "security"="is_granted('IS_CO_ANY', object)"
  48.  *          },
  49.  *          "put"={"security"="is_granted('IS_CO_OPR', object) or is_granted('IS_CO_INS_SPE_COURSE', object.elExam.elCourseAlways)"},
  50.  *          "patch"={"security"="is_granted('IS_CO_OPR', object) or is_granted('IS_CO_INS_SPE_COURSE', object.elExam.elCourseAlways)"},
  51.  *          "patch_change_ord"={
  52.  *              "path"="/el_exam_questions/{id}/change-ord",
  53.  *              "method"="PATCH",
  54.  *              "denormalization_context"={"groups"={"ElExamQuestion:ChangeOrd"}},
  55.  *              "security"="is_granted('IS_CO_OPR', object) or is_granted('IS_CO_INS_SPE_COURSE', object.elExam.elCourseAlways)"
  56.  *          },
  57.  *          "delete"
  58.  *     }
  59.  * )
  60.  * @ApiFilter(SearchFilter::class, properties={"container.id": "exact", "elExam.id": "exact", "questionType": "exact", "translations.question": "partial"})
  61.  * @ApiFilter(OrderFilter::class, properties={"id", "translations.question", "ord": "ASC"})
  62.  * @ORM\Entity(repositoryClass=ElExamQuestionRepository::class)
  63.  */
  64. class ElExamQuestion extends AbstractTranslatable implements ContainerMappedInterfaceOrderMappedInterface
  65. {
  66.     /**
  67.      * Hook timestampable behavior
  68.      * updates createdAt, updatedAt fields
  69.      */
  70.     use TimestampableEntity;
  71.     /**
  72.      * @ORM\OneToMany(targetEntity="ElExamQuestionTranslation", mappedBy="translatable", fetch="EXTRA_LAZY", indexBy="locale", cascade={"PERSIST"}, orphanRemoval=true)
  73.      *
  74.      * @Groups({"ElExamQuestion:Write", "ElExamQuestionTranslationGroup"})
  75.      * @Assert\Valid()
  76.      */
  77.     protected $translations;
  78.     /**
  79.      * @Groups({"ElExamQuestion:Read", "ElExamAnswer:Assessment", "ElExamAnswer:Exam-Report"})
  80.      */
  81.     private $question;
  82.     /**
  83.      * @Groups({"ElExamQuestion:Read", "ElExamAnswer:Assessment"})
  84.      */
  85.     private $description;
  86.     /**
  87.      * @Groups({"ElExamQuestion:With-Answer", "ElExamAnswer:Assessment", "ElExamQuestion:Exam-Complete"})
  88.      */
  89.     private $answerExplanation;
  90.     /**
  91.      * @ORM\Id
  92.      * @ORM\GeneratedValue
  93.      * @ORM\Column(type="integer")
  94.      * @Groups({"ElExamQuestion:Read", "ElExamAnswer:Assessment"})
  95.      */
  96.     private $id;
  97.     /**
  98.      * @ORM\Column(type="string", length=16)
  99.      * @Groups({"ElExamQuestion:Read", "ElExamQuestion:Write", "ElExamAnswer:Assessment", "ElExamAnswer:Exam-Report"})
  100.      */
  101.     private $questionType;
  102.     public const QUESTIONTYPE_SINGLE "SINGLE";
  103.     public const QUESTIONTYPE_MULTI "MULTI";
  104.     public const QUESTIONTYPE_TEXT "TEXT";
  105.     public const QUESTIONTYPE_FILE "FILE";
  106.     /**
  107.      * @ORM\Column(type="integer", nullable=true)
  108.      * @Groups({"ElExamQuestion:Read", "ElExamQuestion:Write", "ElExamAnswer:Assessment", "ElExamAnswer:Exam-Report"})
  109.      */
  110.     private $correctPoint;
  111.     /**
  112.      * @ORM\Column(type="integer", nullable=true)
  113.      * @Groups({"ElExamQuestion:Read", "ElExamQuestion:Write", "ElExamAnswer:Assessment", "ElExamAnswer:Exam-Report"})
  114.      */
  115.     private $wrongPoint;
  116.     /**
  117.      * @ORM\ManyToOne(targetEntity=Container::class)
  118.      * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
  119.      * @Groups({"ElExamQuestion:Write"})
  120.      */
  121.     private $container;
  122.     /**
  123.      * @ORM\ManyToOne(targetEntity=ElExam::class, inversedBy="elExamQuestions")
  124.      * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
  125.      * @Groups({"ElExamQuestion:Read", "ElExamQuestion:Write"})
  126.      */
  127.     public $elExam;
  128.     /**
  129.      * @ORM\OneToMany(targetEntity=ElExamOption::class, mappedBy="elExamQuestion", orphanRemoval=true, cascade={"persist"})
  130.      * @Groups({"ElExamQuestion:Read", "ElExamQuestion:With-Answer", "ElExamQuestion:Write", "ElExamAnswer:Assessment", "ElExamAnswer:Exam-Report"})
  131.      * @Assert\Valid()
  132.      */
  133.     private $elExamOptions;
  134.     /**
  135.      * @ORM\Column(type="integer", nullable=true)
  136.      * @Groups({"ElExamQuestion:Read", "ElExamQuestion:Write", "ElExamAnswer:Assessment"})
  137.      */
  138.     private $ord;
  139.     /**
  140.      * @Groups({"ElExamQuestion:ChangeOrd"})
  141.      */
  142.     private int $newOrd;
  143.     private $ordChangeDirection;
  144.     /**
  145.      * @ORM\OneToMany(targetEntity=ElExamQuestionImage::class, mappedBy="elExamQuestion", orphanRemoval=true, cascade={"persist"})
  146.      * @Groups({"ElExamQuestion:Read", "ElExamQuestion:With-Answer", "ElExamQuestion:Write", "ElExamAnswer:Assessment", "ElExamAnswer:Exam-Report"})
  147.      * @Assert\Valid()
  148.      */
  149.     private $elExamQuestionImages;
  150.     /**
  151.      * @ORM\Column(type="boolean", nullable=true)
  152.      * @Groups({"ElExamQuestion:Read", "ElExamQuestion:Write"})
  153.      */
  154.     private $isRequired;
  155.     public function __construct()
  156.     {
  157.         parent::__construct();
  158.         $this->elExamOptions = new ArrayCollection();
  159.         $this->elExamQuestionImages = new ArrayCollection();
  160.     }
  161.     protected function createTranslation(): TranslationInterface
  162.     {
  163.         return new ElExamQuestionTranslation();
  164.     }
  165.     public function getQuestion(): ?string
  166.     {
  167.         return $this->getTranslation()->getQuestion();
  168.     }
  169.     public function setQuestion(string $question): self
  170.     {
  171.         $this->getTranslation()->setQuestion($question);
  172.         return $this;
  173.     }
  174.     public function getDescription(): ?string
  175.     {
  176.         return $this->getTranslation()->getDescription();
  177.     }
  178.     public function setDescription(string $description): self
  179.     {
  180.         $this->getTranslation()->setDescription($description);
  181.         return $this;
  182.     }
  183.     public function getAnswerExplanation(): ?string
  184.     {
  185.         return $this->getTranslation()->getAnswerExplanation();
  186.     }
  187.     public function setAnswerExplanation(string $answerExplanation): self
  188.     {
  189.         $this->getTranslation()->setAnswerExplanation($answerExplanation);
  190.         return $this;
  191.     }
  192.     public function getId(): ?int
  193.     {
  194.         return $this->id;
  195.     }
  196.     public function getQuestionType(): ?string
  197.     {
  198.         return $this->questionType;
  199.     }
  200.     public function setQuestionType(string $questionType): self
  201.     {
  202.         $this->questionType $questionType;
  203.         return $this;
  204.     }
  205.     public function getCorrectPoint(): ?int
  206.     {
  207.         return $this->correctPoint;
  208.     }
  209.     public function setCorrectPoint(?int $correctPoint): self
  210.     {
  211.         $this->correctPoint $correctPoint;
  212.         return $this;
  213.     }
  214.     public function getWrongPoint(): ?int
  215.     {
  216.         return $this->wrongPoint;
  217.     }
  218.     public function setWrongPoint(?int $wrongPoint): self
  219.     {
  220.         $this->wrongPoint $wrongPoint;
  221.         return $this;
  222.     }
  223.     public function getContainer(): ?Container
  224.     {
  225.         return $this->container;
  226.     }
  227.     public function setContainer(?Container $container): self
  228.     {
  229.         $this->container $container;
  230.         return $this;
  231.     }
  232.     public function getElExam(): ?ElExam
  233.     {
  234.         return $this->elExam;
  235.     }
  236.     public function setElExam(?ElExam $elExam): self
  237.     {
  238.         $this->elExam $elExam;
  239.         return $this;
  240.     }
  241.     /**
  242.      * @return Collection|ElExamOption[]
  243.      */
  244.     public function getElExamOptions(): Collection
  245.     {
  246.         return $this->elExamOptions;
  247.     }
  248.     public function addElExamOption(ElExamOption $elExamOption): self
  249.     {
  250.         if (!$this->elExamOptions->contains($elExamOption)) {
  251.             $this->elExamOptions[] = $elExamOption;
  252.             $elExamOption->setElExamQuestion($this);
  253.         }
  254.         return $this;
  255.     }
  256.     public function removeElExamOption(ElExamOption $elExamOption): self
  257.     {
  258.         if ($this->elExamOptions->removeElement($elExamOption)) {
  259.             // set the owning side to null (unless already changed)
  260.             if ($elExamOption->getElExamQuestion() === $this) {
  261.                 $elExamOption->setElExamQuestion(null);
  262.             }
  263.         }
  264.         return $this;
  265.     }
  266.     public function removeAllElExamOptions(): self
  267.     {
  268.         foreach ($this->elExamOptions as $elExamOption) {
  269.             $this->removeElExamOption($elExamOption);
  270.         }
  271.         return $this;
  272.     }
  273.     public function getClone(ElExamQuestion $source null): self
  274.     {
  275.         if (empty($source)) {
  276.             $source $this;
  277.         }
  278.         $target = new ElExamQuestion();
  279.         $target
  280.             ->setQuestionType($source->getQuestionType())
  281.             ->setCorrectPoint($source->getCorrectPoint())
  282.             ->setWrongPoint($source->getWrongPoint())
  283.             ->setContainer($source->getContainer())
  284.             ->setElExam($source->getElExam())
  285.             ->setOrd($source->getOrd())
  286.         ;
  287.         foreach ($source->getTranslations() as $s) {
  288.             $newT = new ElExamQuestionTranslation();
  289.             $newT
  290.                 ->setQuestion($s->getQuestion())
  291.                 ->setDescription($s->getDescription())
  292.                 ->setAnswerExplanation($s->getAnswerExplanation())
  293.                 ->setLocale($s->getLocale())
  294.             ;
  295.             $target->addTranslation($newT);
  296.         }
  297.         foreach ($source->getElExamOptions() as $s) {
  298.             $target->addElExamOption($s->getClone());
  299.         }
  300.         return $target;
  301.     }
  302.     public function getOrd(): ?int
  303.     {
  304.         return $this->ord;
  305.     }
  306.     public function setOrd(?int $ord): self
  307.     {
  308.         $this->ord $ord;
  309.         return $this;
  310.     }
  311.     public function getOrdParents(): array
  312.     {
  313.         return [
  314.             'container' => $this->getContainer(),
  315.             'elExam' => $this->getElExam()
  316.         ];
  317.     }
  318.     public function getOrdChangeDirection()
  319.     {
  320.         return $this->ordChangeDirection;
  321.     }
  322.     public function getNewOrd(): int
  323.     {
  324.         return $this->newOrd ?? 0;
  325.     }
  326.     public function setNewOrd(int $newOrd): self
  327.     {
  328.         $oldOrd $this->ord;
  329.         $this->newOrd $newOrd;
  330.         $this->ord $newOrd;
  331.         $this->ordChangeDirection = ($this->newOrd $oldOrd) ? 'desc' 'asc';
  332.         return $this;
  333.     }
  334.     /**
  335.      * @return Collection<int, ElExamQuestionImage>
  336.      */
  337.     public function getElExamQuestionImages(): Collection
  338.     {
  339.         return $this->elExamQuestionImages;
  340.     }
  341.     public function addElExamQuestionImage(ElExamQuestionImage $elExamQuestionImage): self
  342.     {
  343.         if (!$this->elExamQuestionImages->contains($elExamQuestionImage)) {
  344.             $this->elExamQuestionImages[] = $elExamQuestionImage;
  345.             $elExamQuestionImage->setElExamQuestion($this);
  346.         }
  347.         return $this;
  348.     }
  349.     public function removeElExamQuestionImage(ElExamQuestionImage $elExamQuestionImage): self
  350.     {
  351.         if ($this->elExamQuestionImages->removeElement($elExamQuestionImage)) {
  352.             // set the owning side to null (unless already changed)
  353.             if ($elExamQuestionImage->getElExamQuestion() === $this) {
  354.                 $elExamQuestionImage->setElExamQuestion(null);
  355.             }
  356.         }
  357.         return $this;
  358.     }
  359.     public function removeAllElQuestionImages(): self
  360.     {
  361.         foreach ($this->elExamQuestionImages as $elExamQuestionImage) {
  362.             $this->removeElExamQuestionImage($elExamQuestionImage);
  363.         }
  364.         return $this;
  365.     }
  366.     public function isIsRequired(): ?bool
  367.     {
  368.         return $this->isRequired;
  369.     }
  370.     public function setIsRequired(?bool $isRequired): self
  371.     {
  372.         $this->isRequired $isRequired;
  373.         return $this;
  374.     }
  375. }