src/Entity/ElExam.php line 98

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use Doctrine\ORM\Mapping as ORM;
  4. use App\Entity\ElExamTranslation;
  5. use App\Entity\Model\BulletPoint;
  6. use App\Repository\ElExamRepository;
  7. use ApiPlatform\Core\Annotation\ApiFilter;
  8. use App\Entity\Traits\TimestampableEntity;
  9. use Doctrine\Common\Collections\Collection;
  10. use ApiPlatform\Core\Annotation\ApiProperty;
  11. use ApiPlatform\Core\Annotation\ApiResource;
  12. use App\Entity\Interfaces\OrderMappedInterface;
  13. use Doctrine\Common\Collections\ArrayCollection;
  14. use App\Entity\Interfaces\ElCopyRestrictInterface;
  15. use App\Entity\Interfaces\ContainerMappedInterface;
  16. use App\Entity\Interfaces\NewsfeedCreatorInterface;
  17. use Symfony\Component\Serializer\Annotation\Groups;
  18. use App\Entity\Interfaces\OperationLogMappedInterface;
  19. use Symfony\Component\Validator\Constraints as Assert;
  20. use App\Entity\Interfaces\ElCourseIndexUpdateInterface;
  21. use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter;
  22. use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
  23. use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
  24. use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\BooleanFilter;
  25. use Locastic\ApiPlatformTranslationBundle\Model\AbstractTranslatable;
  26. use Locastic\ApiPlatformTranslationBundle\Model\TranslationInterface;
  27. /**
  28.  * @ApiResource(
  29.  *      attributes={"security"="is_granted('ROLE_OPERATOR')", "filters"={"translation.groups"}},
  30.  *      normalizationContext={"groups"={"ElExam:Read"}, "skip_null_values"=false},
  31.  *      denormalizationContext={"groups"={"ElExam:Write"}},
  32.  *      collectionOperations={
  33.  *          "get"={"pagination_use_output_walkers"=true},
  34.  *          "get_for_select"={
  35.  *              "path"="/el_exams/get-for-select",
  36.  *              "method"="GET",
  37.  *              "normalization_context"={"groups"={"ElExam:Select"}, "skip_null_values"=false},
  38.  *              "pagination_enabled"=false
  39.  *          },
  40.  *          "get_public"={
  41.  *              "path"="/el_exams/get-public",
  42.  *              "method"="GET",
  43.  *              "normalization_context"={"groups"={"ElExam:Read"}, "skip_null_values"=false},
  44.  *              "security"="is_granted('IS_AUTHENTICATED_FULLY')"
  45.  *          },
  46.  *          "get_my"={
  47.  *              "path"="/el_exams/get-my",
  48.  *              "method"="GET",
  49.  *              "normalization_context"={"groups"={"ElExam:Read"}, "skip_null_values"=false},
  50.  *              "security"="is_granted('IS_AUTHENTICATED_FULLY')",
  51.  *              "pagination_use_output_walkers"=true
  52.  *          },
  53.  *          "post"={
  54.  *              "security"="is_granted('ROLE_OPERATOR') or is_granted('ROLE_INSTRUCTOR')"
  55.  *          },
  56.  *          "post_clone"={
  57.  *              "route_name"="api_el_exams_clone_collection",
  58.  *              "method"="POST",
  59.  *              "denormalization_context"={"groups"={"ElExam:Clone"}}
  60.  *          },
  61.  *          "post_send_result"={
  62.  *              "route_name"="api_el_exams_send_result_collection",
  63.  *              "method"="POST",
  64.  *              "denormalization_context"={"groups"={"ElExam:SendResult"}}
  65.  *          }
  66.  *      },
  67.  *      itemOperations={
  68.  *          "get"={
  69.  *              "security"="is_granted('IS_AUTHENTICATED_FULLY', object)",
  70.  *              "normalization_context"={"groups"={"ElExam:Read"}, "skip_null_values"=false}
  71.  *          },
  72.  *          "get_with_solution"={
  73.  *              "path"="/el_exams/{id}/get-with-solution",
  74.  *              "method"="GET",
  75.  *              "security"="is_granted('IS_AUTHENTICATED_FULLY', object)",
  76.  *              "normalization_context"={"groups"={"ElExam:Read", "ElExam:Read-Solution"}, "skip_null_values"=false}
  77.  *          },
  78.  *          "put"={"security"="is_granted('IS_CO_OPR', object) or is_granted('IS_CO_INS_SPE_COURSE', object.elCourseAlways)"},
  79.  *          "patch"={"security"="is_granted('IS_CO_OPR', object) or is_granted('IS_CO_INS_SPE_COURSE', object.elCourseAlways)"},
  80.  *          "patch_change_ord"={
  81.  *              "path"="/el_exams/{id}/change-ord",
  82.  *              "method"="PATCH",
  83.  *              "denormalization_context"={"groups"={"ElExam:ChangeOrd", "ElExam:Move"}},
  84.  *              "security"="is_granted('IS_CO_OPR', object) or is_granted('IS_CO_INS_SPE_COURSE', object.elCourseAlways)"
  85.  *          },
  86.  *          "delete"={"security"="is_granted('IS_CO_OPR', object) or is_granted('IS_CO_INS_SPE_COURSE', object.elCourseAlways)"}
  87.  *     }
  88.  * )
  89.  * @ApiFilter(SearchFilter::class, properties={"id": "exact", "container.id": "exact", "elCourseAlways.id": "exact", "elCourse.id": "exact", "elLession.id": "exact", "elLesstionTopic.id": "exact", "elTask.id": "exact", "solutionType": "exact", "translations.title": "partial", "elExamTags.id": "exact", "examLevel": "exact"})
  90.  * @ApiFilter(BooleanFilter::class, properties={"isConsiderForPass"})
  91.  * @ApiFilter(DateFilter::class, properties={"start", "end"})
  92.  * @ApiFilter(OrderFilter::class, properties={"ord": "ASC", "translations.name", "id"})
  93.  * @ORM\Entity(repositoryClass=ElExamRepository::class)
  94.  */
  95. class ElExam extends AbstractTranslatable implements ContainerMappedInterfaceOrderMappedInterfaceElCourseIndexUpdateInterfaceNewsfeedCreatorInterfaceOperationLogMappedInterfaceElCopyRestrictInterface
  96. {
  97.     /**
  98.      * Hook timestampable behavior
  99.      * updates createdAt, updatedAt fields
  100.      */
  101.     use TimestampableEntity;
  102.     /**
  103.      * @ORM\OneToMany(targetEntity="ElExamTranslation", mappedBy="translatable", fetch="EXTRA_LAZY", indexBy="locale", cascade={"PERSIST"}, orphanRemoval=true)
  104.      *
  105.      * @Groups({"ElExam:Write", "ElExamTranslationGroup", "ElCourse:Read", "ElLession:Read", "ElLessionTopic:Read", "ElTask:Read"})
  106.      * @Assert\Valid()
  107.      */
  108.     protected $translations;
  109.     /**
  110.      * @Groups({"ElExam:Read", "ElCourse:Read", "ElLession:Detail", "ElLession:Read", "ElLessionTopic:Read", "ElTask:Read", "ElTask:Get-Topic", "ElExamAttempt:Read", "ElExam:Select", "Survey:Read"})
  111.      */
  112.     private $title;
  113.     /**
  114.      * @Groups({"ElExam:Read"})
  115.      */
  116.     private $description;
  117.     /**
  118.      * @Groups({"ElExam:Read"})
  119.      */
  120.     private $instruction;
  121.     /**
  122.      * @Groups({"ElExam:Read-Solution"})
  123.      */
  124.     private $uploadVideo;
  125.     /**
  126.      * @Groups({"ElExam:Read-Solution"})
  127.      */
  128.     private $session;
  129.     /**
  130.      * @Groups({"ElExam:Read-Solution"})
  131.      */
  132.     private $solutionDescription;
  133.     /**
  134.      * @ORM\Id
  135.      * @ORM\GeneratedValue
  136.      * @ORM\Column(type="integer")
  137.      * @Groups({"ElExam:Read", "ElCourse:Read", "ElLession:Detail", "ElLession:Read", "ElLessionTopic:Read", "ElTask:Read", "ElTask:Get-Topic", "ElExamAttempt:Read", "ElExam:Select", "Survey:Read"})
  138.      */
  139.     private $id;
  140.     /**
  141.      * @ORM\Column(type="integer", nullable=true)
  142.      * @Groups({"ElExam:Read", "ElExam:Write"})
  143.      */
  144.     private $passingPoint;
  145.     /**
  146.      * @ORM\Column(type="integer", nullable=true)
  147.      * @Groups({"ElExam:Read", "ElExam:Write", "ElCourse:Read", "ElLession:Detail", "ElTask:Read", "ElTask:Get-Topic", "ElExamAttempt:Read"})
  148.      */
  149.     private $duration;
  150.     /**
  151.      * @ORM\Column(type="boolean", nullable=true)
  152.      * @Groups({"ElExam:Read", "ElExam:Write"})
  153.      */
  154.     private $isShowLeaderBoard;
  155.     /**
  156.      * @ORM\Column(type="boolean", nullable=true)
  157.      * @Groups({"ElExam:Read", "ElExam:Write"})
  158.      */
  159.     private $isAllowShowSolution;
  160.     /**
  161.      * @ORM\Column(type="boolean", nullable=true)
  162.      * @Groups({"ElExam:Read", "ElExam:Write"})
  163.      */
  164.     private $isAllowShowResult;
  165.     /**
  166.      * @ORM\Column(type="boolean", nullable=true)
  167.      * @Groups({"ElExam:Read", "ElExam:Write"})
  168.      */
  169.     private $isAllowShowShortResult;
  170.     /**
  171.      * @ORM\Column(type="boolean", nullable=true)
  172.      * @Groups({"ElExam:Read", "ElExam:Write"})
  173.      */
  174.     private $isAllowReAttempt;
  175.     /**
  176.      * @ORM\Column(type="string", length=16, nullable=true)
  177.      * @ApiProperty(
  178.      *     attributes={
  179.      *         "openapi_context"={
  180.      *             "type"="string",
  181.      *             "enum"={self::SOLUTIONTYPE_DOCUMENT, self::SOLUTIONTYPE_VIDEO, self::SOLUTIONTYPE_SESSION}
  182.      *         }
  183.      *     }
  184.      * )
  185.      * @Groups({"ElExam:Read", "ElExam:Write"})
  186.      */
  187.     private $solutionType;
  188.     public const SOLUTIONTYPE_DOCUMENT "DOCUMENT";
  189.     public const SOLUTIONTYPE_VIDEO "VIDEO";
  190.     public const SOLUTIONTYPE_SESSION "SESSION";
  191.     /**
  192.      * @ORM\ManyToOne(targetEntity=Container::class)
  193.      * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
  194.      * @Groups({"ElExam:Write"})
  195.      */
  196.     private $container;
  197.     /**
  198.      * @ORM\ManyToOne(targetEntity=ElTask::class, inversedBy="elExams")
  199.      * @ORM\JoinColumn(nullable=true, onDelete="CASCADE")
  200.      * @Groups({"ElExam:Read", "ElExam:Write", "ElExamAttempt:Read", "ElExam:Clone", "ElExam:Move"})
  201.      */
  202.     private $elTask;
  203.     /**
  204.      * @ORM\OneToMany(targetEntity=ElExamQuestion::class, mappedBy="elExam", orphanRemoval=true, cascade={"persist"})
  205.      */
  206.     private $elExamQuestions;
  207.     /**
  208.      * @ORM\ManyToOne(targetEntity=ElLessionTopic::class, inversedBy="elExams")
  209.      * @ORM\JoinColumn(nullable=true, onDelete="CASCADE")
  210.      * @Groups({"ElExam:Read", "ElExam:Write", "ElExamAttempt:Read", "ElExam:Clone", "ElExam:Move"})
  211.      */
  212.     private $elLesstionTopic;
  213.     /**
  214.      * @ORM\ManyToOne(targetEntity=ElLession::class, inversedBy="elExams")
  215.      * @ORM\JoinColumn(nullable=true, onDelete="CASCADE")
  216.      * @Groups({"ElExam:Read", "ElExam:Write", "ElExamAttempt:Read", "ElExam:Clone", "ElExam:Move"})
  217.      */
  218.     private $elLession;
  219.     /**
  220.      * @ORM\ManyToOne(targetEntity=ElCourse::class, inversedBy="elExams")
  221.      * @ORM\JoinColumn(nullable=true, onDelete="CASCADE")
  222.      * @Groups({"ElExam:Read", "ElExam:Write", "ElExamAttempt:Read", "ElExam:Clone", "ElExam:Move"})
  223.      */
  224.     private $elCourse;
  225.     /**
  226.      * @ORM\ManyToOne(targetEntity=ElCourse::class, inversedBy="elAllExams")
  227.      * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
  228.      * @Groups({"ElExam:Read", "ElExam:Write", "ElExamAttempt:Read", "ElExam:Clone"})
  229.      */
  230.     public $elCourseAlways;
  231.     /**
  232.      * @ORM\Column(type="boolean", nullable=true)
  233.      * @Groups({"ElExam:Read", "ElExam:Write", "ElLession:Detail", "ElTask:Read", "ElTask:Get-Topic", "ElExamAttempt:Read"})
  234.      */
  235.     private $isConsiderForPass;
  236.     /**
  237.      * @ORM\Column(type="string", length=16)
  238.      * @ApiProperty(
  239.      *     attributes={
  240.      *         "openapi_context"={
  241.      *             "type"="string",
  242.      *             "enum"={self::EXAMLEVEL_TASK, self::EXAMLEVEL_LESSIONTOPIC, self::EXAMLEVEL_LESSION, self::EXAMLEVEL_COURSE}
  243.      *         }
  244.      *     }
  245.      * )
  246.      *
  247.      * @Groups({"ElExam:Read", "ElExam:Write", "ElExam:Clone", "ElExam:Move"})
  248.      */
  249.     private $examLevel;
  250.     public const EXAMLEVEL_TASK "TASK";
  251.     public const EXAMLEVEL_LESSIONTOPIC "LESSIONTOPIC";
  252.     public const EXAMLEVEL_LESSION "LESSION";
  253.     public const EXAMLEVEL_COURSE "COURSE";
  254.     /**
  255.      * @ORM\Column(type="integer", nullable=true)
  256.      * @Groups({"ElExam:Read", "ElExam:Write", "ElCourse:Read", "ElLession:Detail", "ElLession:Read", "ElLessionTopic:Read", "ElTask:Read", "ElTask:Get-Topic"})
  257.      */
  258.     private $ord;
  259.     /**
  260.      * @ORM\ManyToMany(targetEntity=ElExamTag::class, inversedBy="elExams", cascade={"persist"})
  261.      * @Groups({"ElExam:Read", "ElExam:Write"})
  262.      */
  263.     private $elExamTags;
  264.     /**
  265.      * @ORM\OneToMany(targetEntity=ElExamAttempt::class, mappedBy="elExam", orphanRemoval=true)
  266.      */
  267.     private $elExamAttempts;
  268.     /**
  269.      * @ORM\ManyToMany(targetEntity=DocFile::class)
  270.      * @Groups({"ElExam:Write", "ElExam:Read-Solution"})
  271.      */
  272.     private $documents;
  273.     /**
  274.      * @Groups({"ElExam:ChangeOrd"})
  275.      */
  276.     private int $newOrd;
  277.     private $ordChangeDirection;
  278.     /**
  279.      * @ORM\Column(type="datetime", nullable=true)
  280.      * @Groups({"ElExam:Read", "ElExam:Write", "ElCourse:Read", "ElLession:Detail", "ElLession:Read", "ElLessionTopic:Read", "ElTask:Read", "ElTask:Get-Topic", "ElExamAttempt:Read"})
  281.      */
  282.     private $start;
  283.     /**
  284.      * @ORM\Column(type="datetime", nullable=true)
  285.      * @Groups({"ElExam:Read", "ElExam:Write", "ElCourse:Read", "ElLession:Detail", "ElLession:Read", "ElLessionTopic:Read", "ElTask:Read", "ElTask:Get-Topic", "ElExamAttempt:Read"})
  286.      */
  287.     private $end;
  288.     /**
  289.      * @ORM\Column(type="integer", nullable=true)
  290.      * @Groups({"ElExam:Read", "ElExam:Write"})
  291.      */
  292.     private $reminderBefore;
  293.     /**
  294.      * @ORM\Column(type="integer", nullable=true)
  295.      * @Groups({"ElExam:Read", "ElExam:Write"})
  296.      */
  297.     private $reminderAfter;
  298.     /**
  299.      * @ORM\Column(type="boolean", nullable=true)
  300.      * @Groups({"ElExam:Read", "ElExam:Write"})
  301.      */
  302.     private $isReminderBefore;
  303.     /**
  304.      * @ORM\Column(type="boolean", nullable=true)
  305.      * @Groups({"ElExam:Read", "ElExam:Write"})
  306.      */
  307.     private $isReminderAfter;
  308.     /**
  309.      * @ORM\Column(type="boolean", nullable=true)
  310.      * @Groups({"ElExam:Read", "ElExam:Write"})
  311.      */
  312.     private $isAllowRandom;
  313.     /**
  314.      * @ORM\OneToMany(targetEntity=CommonComment::class, mappedBy="elExam")
  315.      */
  316.     private $commonComments;
  317.     /**
  318.      * @ORM\Column(type="boolean", nullable=true)
  319.      * @Groups({"ElExam:Read", "ElExam:Write"})
  320.      */
  321.     private $isCommentEnable;
  322.     /**
  323.      * @ORM\Column(type="boolean", nullable=true)
  324.      * @Groups({"ElExam:Read", "ElExam:Write"})
  325.      */
  326.     private $isReviewEnable;
  327.     /**
  328.      * @ORM\Column(type="boolean", nullable=true)
  329.      * @Groups({"ElExam:Read", "ElExam:Write"})
  330.      */
  331.     private $isShowPoints;
  332.     /**
  333.      * @Groups({"ElExam:Clone", "ElExam:SendResult"})
  334.      */
  335.     private int $cloneId;
  336.     /**
  337.      * @ORM\ManyToMany(targetEntity=UserGroup::class)
  338.      * @Groups({"ElExam:Read", "ElExam:Write"})
  339.      */
  340.     private $userGroups;
  341.     /**
  342.      * @ORM\Column(type="array", nullable=true)
  343.      * @Groups({"ElExam:Read", "ElExam:Write"})
  344.      */
  345.     private $bulletPoints = [];
  346.     /**
  347.      * @ORM\Column(type="boolean", nullable=true)
  348.      * @Groups({"ElExam:Read", "ElExam:Write", "ElExamAttempt:Read"})
  349.      */
  350.     private $isStepByStep;
  351.     /**
  352.      * @ORM\OneToMany(targetEntity=SurveyTrigger::class, mappedBy="elExam")
  353.      */
  354.     private $surveyTriggers;
  355.     /**
  356.      * @ORM\Column(type="boolean", nullable=true)
  357.      * @Groups({"ElExam:Read", "ElExam:Write"})
  358.      */
  359.     private $isAutoResultSend;
  360.     /**
  361.      * @ORM\Column(type="boolean", nullable=true)
  362.      * @Groups({"ElExam:Read", "ElExam:Write"})
  363.      */
  364.     private $isOnlyChoiceQuestion;
  365.     /**
  366.      * @ORM\Column(type="boolean", nullable=true)
  367.      * @Groups({"ElExam:Read", "ElExam:Write"})
  368.      */
  369.     private $isOnlyContinueOnPass;
  370.     public function __construct()
  371.     {
  372.         parent::__construct();
  373.         $this->elExamQuestions = new ArrayCollection();
  374.         $this->elExamTags = new ArrayCollection();
  375.         $this->elExamAttempts = new ArrayCollection();
  376.         $this->documents = new ArrayCollection();
  377.         $this->commonComments = new ArrayCollection();
  378.         $this->userGroups = new ArrayCollection();
  379.         $this->surveyTriggers = new ArrayCollection();
  380.         $bulletPointModel = new BulletPoint();
  381.         $this->bulletPoints $bulletPointModel->getProperties();
  382.     }
  383.     protected function createTranslation(): TranslationInterface
  384.     {
  385.         return new ElExamTranslation();
  386.     }
  387.     public function getTitle(): ?string
  388.     {
  389.         return $this->getTranslation()->getTitle();
  390.     }
  391.     public function setTitle(string $title): self
  392.     {
  393.         $this->getTranslation()->setTitle($title);
  394.         return $this;
  395.     }
  396.     public function getDescription(): ?string
  397.     {
  398.         return $this->getTranslation()->getDescription();
  399.     }
  400.     public function setDescription(string $description): self
  401.     {
  402.         $this->getTranslation()->setDescription($description);
  403.         return $this;
  404.     }
  405.     public function getInstruction(): ?string
  406.     {
  407.         return $this->getTranslation()->getInstruction();
  408.     }
  409.     public function setInstruction(string $instruction): self
  410.     {
  411.         $this->getTranslation()->setInstruction($instruction);
  412.         return $this;
  413.     }
  414.     public function getUploadVideo(): ?string
  415.     {
  416.         return $this->getTranslation()->getUploadVideo();
  417.     }
  418.     public function setUploadVideo(string $uploadVideo): self
  419.     {
  420.         $this->getTranslation()->setUploadVideo($uploadVideo);
  421.         return $this;
  422.     }
  423.     public function getSession()
  424.     {
  425.         return $this->getTranslation()->getSession();
  426.     }
  427.     public function setSession($session): self
  428.     {
  429.         $this->getTranslation()->setSession($session);
  430.         return $this;
  431.     }
  432.     public function getSolutionDescription(): ?string
  433.     {
  434.         return $this->getTranslation()->getSolutionDescription();
  435.     }
  436.     public function setSolutionDescription(string $solutionDescription): self
  437.     {
  438.         $this->getTranslation()->setSolutionDescription($solutionDescription);
  439.         return $this;
  440.     }
  441.     public function getId(): ?int
  442.     {
  443.         return $this->id;
  444.     }
  445.     public function getPassingPoint(): ?int
  446.     {
  447.         return $this->passingPoint;
  448.     }
  449.     public function setPassingPoint(?int $passingPoint): self
  450.     {
  451.         $this->passingPoint $passingPoint;
  452.         return $this;
  453.     }
  454.     public function getDuration(): ?int
  455.     {
  456.         return $this->duration;
  457.     }
  458.     public function setDuration(?int $duration): self
  459.     {
  460.         $this->duration $duration;
  461.         return $this;
  462.     }
  463.     public function getIsShowLeaderBoard(): ?bool
  464.     {
  465.         return $this->isShowLeaderBoard;
  466.     }
  467.     public function setIsShowLeaderBoard(?bool $isShowLeaderBoard): self
  468.     {
  469.         $this->isShowLeaderBoard $isShowLeaderBoard;
  470.         return $this;
  471.     }
  472.     public function getIsAllowShowSolution(): ?bool
  473.     {
  474.         return $this->isAllowShowSolution;
  475.     }
  476.     public function setIsAllowShowSolution(?bool $isAllowShowSolution): self
  477.     {
  478.         $this->isAllowShowSolution $isAllowShowSolution;
  479.         return $this;
  480.     }
  481.     public function getIsAllowShowResult(): ?bool
  482.     {
  483.         return $this->isAllowShowResult;
  484.     }
  485.     public function setIsAllowShowResult(?bool $isAllowShowResult): self
  486.     {
  487.         $this->isAllowShowResult $isAllowShowResult;
  488.         return $this;
  489.     }
  490.     public function getIsAllowShowShortResult(): ?bool
  491.     {
  492.         return $this->isAllowShowShortResult;
  493.     }
  494.     public function setIsAllowShowShortResult(?bool $isAllowShowShortResult): self
  495.     {
  496.         $this->isAllowShowShortResult $isAllowShowShortResult;
  497.         return $this;
  498.     }
  499.     public function getIsAllowReAttempt(): ?bool
  500.     {
  501.         return $this->isAllowReAttempt;
  502.     }
  503.     public function setIsAllowReAttempt(?bool $isAllowReAttempt): self
  504.     {
  505.         $this->isAllowReAttempt $isAllowReAttempt;
  506.         return $this;
  507.     }
  508.     public function getSolutionType(): ?string
  509.     {
  510.         return $this->solutionType;
  511.     }
  512.     public function setSolutionType(?string $solutionType): self
  513.     {
  514.         $this->solutionType $solutionType;
  515.         return $this;
  516.     }
  517.     public function getContainer(): ?Container
  518.     {
  519.         return $this->container;
  520.     }
  521.     public function setContainer(?Container $container): self
  522.     {
  523.         $this->container $container;
  524.         return $this;
  525.     }
  526.     public function getElTask(): ?ElTask
  527.     {
  528.         return $this->elTask;
  529.     }
  530.     public function setElTask(?ElTask $elTask): self
  531.     {
  532.         $this->elTask $elTask;
  533.         return $this;
  534.     }
  535.     /**
  536.      * @return Collection|ElExamQuestion[]
  537.      */
  538.     public function getElExamQuestions(): Collection
  539.     {
  540.         return $this->elExamQuestions;
  541.     }
  542.     public function addElExamQuestion(ElExamQuestion $elExamQuestion): self
  543.     {
  544.         if (!$this->elExamQuestions->contains($elExamQuestion)) {
  545.             $this->elExamQuestions[] = $elExamQuestion;
  546.             $elExamQuestion->setElExam($this);
  547.         }
  548.         return $this;
  549.     }
  550.     public function removeElExamQuestion(ElExamQuestion $elExamQuestion): self
  551.     {
  552.         if ($this->elExamQuestions->removeElement($elExamQuestion)) {
  553.             // set the owning side to null (unless already changed)
  554.             if ($elExamQuestion->getElExam() === $this) {
  555.                 $elExamQuestion->setElExam(null);
  556.             }
  557.         }
  558.         return $this;
  559.     }
  560.     /**
  561.      * @Groups({"ElExam:Read"})
  562.      */
  563.     public function getTotalElExamQuestions()
  564.     {
  565.         return count($this->elExamQuestions);
  566.     }
  567.     public function getElLesstionTopic(): ?ElLessionTopic
  568.     {
  569.         return $this->elLesstionTopic;
  570.     }
  571.     public function setElLesstionTopic(?ElLessionTopic $elLesstionTopic): self
  572.     {
  573.         $this->elLesstionTopic $elLesstionTopic;
  574.         return $this;
  575.     }
  576.     public function getElLession(): ?ElLession
  577.     {
  578.         return $this->elLession;
  579.     }
  580.     public function setElLession(?ElLession $elLession): self
  581.     {
  582.         $this->elLession $elLession;
  583.         return $this;
  584.     }
  585.     public function getElCourse(): ?ElCourse
  586.     {
  587.         return $this->elCourse;
  588.     }
  589.     public function setElCourse(?ElCourse $elCourse): self
  590.     {
  591.         $this->elCourse $elCourse;
  592.         return $this;
  593.     }
  594.     public function getElCourseAlways(): ?ElCourse
  595.     {
  596.         return $this->elCourseAlways;
  597.     }
  598.     public function setElCourseAlways(?ElCourse $elCourseAlways): self
  599.     {
  600.         $this->elCourseAlways $elCourseAlways;
  601.         return $this;
  602.     }
  603.     public function getIsConsiderForPass(): ?bool
  604.     {
  605.         return $this->isConsiderForPass;
  606.     }
  607.     public function setIsConsiderForPass(?bool $isConsiderForPass): self
  608.     {
  609.         $this->isConsiderForPass $isConsiderForPass;
  610.         return $this;
  611.     }
  612.     public function getExamLevel(): ?string
  613.     {
  614.         return $this->examLevel;
  615.     }
  616.     public function setExamLevel(string $examLevel): self
  617.     {
  618.         $this->examLevel $examLevel;
  619.         return $this;
  620.     }
  621.     public function getOrd(): ?int
  622.     {
  623.         return $this->ord;
  624.     }
  625.     public function setOrd(?int $ord): self
  626.     {
  627.         $this->ord $ord;
  628.         return $this;
  629.     }
  630.     public function getOrdParents(): array
  631.     {
  632.         $parents = [
  633.             'container' => $this->getContainer()
  634.         ];
  635.         if ($this->getExamLevel() === self::EXAMLEVEL_COURSE) {
  636.             $parents['elCourse'] = $this->getElCourse();
  637.         } elseif ($this->getExamLevel() === self::EXAMLEVEL_LESSION) {
  638.             $parents['elLession'] = $this->getElLession();
  639.         } elseif ($this->getExamLevel() === self::EXAMLEVEL_LESSIONTOPIC) {
  640.             $parents['elLesstionTopic'] = $this->getElLesstionTopic();
  641.         } elseif ($this->getExamLevel() === self::EXAMLEVEL_TASK) {
  642.             $parents['elTask'] = $this->getElTask();
  643.         }
  644.         return $parents;
  645.     }
  646.     public function getOrdChangeDirection()
  647.     {
  648.         return $this->ordChangeDirection;
  649.     }
  650.     /**
  651.      * @return Collection|ElExamTag[]
  652.      */
  653.     public function getElExamTags(): Collection
  654.     {
  655.         return $this->elExamTags;
  656.     }
  657.     public function getTagsArray()
  658.     {
  659.         $tags = [];
  660.         foreach ($this->elExamTags as $tag) {
  661.             $tags[] = $tag->getName();
  662.         }
  663.         return $tags;
  664.     }
  665.     public function addElExamTag(ElExamTag $elExamTag): self
  666.     {
  667.         if (!$this->elExamTags->contains($elExamTag)) {
  668.             $this->elExamTags[] = $elExamTag;
  669.         }
  670.         return $this;
  671.     }
  672.     public function removeElExamTag(ElExamTag $elExamTag): self
  673.     {
  674.         $this->elExamTags->removeElement($elExamTag);
  675.         return $this;
  676.     }
  677.     public function reAttachTags(): self
  678.     {
  679.         $tags $this->elExamTags;
  680.         foreach ($tags as $tag) {
  681.             $nt = clone $tag;
  682.             $nt->setContainer($this->getContainer());
  683.             $this->removeElExamTag($tag);
  684.             $this->addElExamTag($nt);
  685.         }
  686.         return $this;
  687.     }
  688.     /**
  689.      * @return Collection|ElExamAttempt[]
  690.      */
  691.     public function getElExamAttempts(): Collection
  692.     {
  693.         return $this->elExamAttempts;
  694.     }
  695.     public function addElExamAttempt(ElExamAttempt $elExamAttempt): self
  696.     {
  697.         if (!$this->elExamAttempts->contains($elExamAttempt)) {
  698.             $this->elExamAttempts[] = $elExamAttempt;
  699.             $elExamAttempt->setElExam($this);
  700.         }
  701.         return $this;
  702.     }
  703.     public function removeElExamAttempt(ElExamAttempt $elExamAttempt): self
  704.     {
  705.         if ($this->elExamAttempts->removeElement($elExamAttempt)) {
  706.             // set the owning side to null (unless already changed)
  707.             if ($elExamAttempt->getElExam() === $this) {
  708.                 $elExamAttempt->setElExam(null);
  709.             }
  710.         }
  711.         return $this;
  712.     }
  713.     /**
  714.      * @return Collection|DocFile[]
  715.      */
  716.     public function getDocuments(): Collection
  717.     {
  718.         return $this->documents;
  719.     }
  720.     public function addDocument(DocFile $document): self
  721.     {
  722.         if (!$this->documents->contains($document)) {
  723.             $this->documents[] = $document;
  724.         }
  725.         return $this;
  726.     }
  727.     public function removeDocument(DocFile $document): self
  728.     {
  729.         $this->documents->removeElement($document);
  730.         return $this;
  731.     }
  732.     public function getClone(ElExam $source null): self
  733.     {
  734.         if (empty($source)) {
  735.             $source $this;
  736.         }
  737.         $target = new ElExam();
  738.         $target
  739.             ->setPassingPoint($source->getPassingPoint())
  740.             ->setDuration($source->getDuration())
  741.             ->setIsShowLeaderBoard($source->getIsShowLeaderBoard())
  742.             ->setIsAllowShowSolution($source->getIsAllowShowSolution())
  743.             ->setIsAllowShowResult($source->getIsAllowShowResult())
  744.             ->setIsAllowShowShortResult($source->getIsAllowShowShortResult())
  745.             ->setIsAllowReAttempt($source->getIsAllowReAttempt())
  746.             ->setSolutionType($source->getSolutionType())
  747.             ->setContainer($source->getContainer())
  748.             ->setElTask($source->getElTask())
  749.             ->setElCourseAlways($source->getElCourseAlways())
  750.             ->setIsConsiderForPass($source->getIsConsiderForPass())
  751.             ->setExamLevel($source->getExamLevel())
  752.             ->setStart($source->getElCourseAlways()->getAvailableStart())
  753.             ->setEnd($source->getElCourseAlways()->getAvailableEnd())
  754.         ;
  755.         foreach ($source->getTranslations() as $s) {
  756.             $newT = new ElExamTranslation();
  757.             $newT
  758.                 ->setTitle($s->getTitle())
  759.                 ->setDescription($s->getDescription())
  760.                 ->setInstruction($s->getInstruction())
  761.                 ->setUploadVideo($s->getUploadVideo())
  762.                 ->setSession($s->getSession())
  763.                 ->setSolutionDescription($s->getSolutionDescription())
  764.                 ->setLocale($s->getLocale())
  765.             ;
  766.             $target->addTranslation($newT);
  767.         }
  768.         foreach ($source->getElExamTags() as $s) {
  769.             $target->addElExamTag($s);
  770.         }
  771.         foreach ($source->getDocuments() as $s) {
  772.             $target->addDocument($s);
  773.         }
  774.         foreach ($source->getElExamQuestions() as $s) {
  775.             $target->addElExamQuestion($s->getClone());
  776.         }
  777.         return $target;
  778.     }
  779.     public function getNewOrd(): int
  780.     {
  781.         return $this->newOrd ?? 0;
  782.     }
  783.     public function setNewOrd(int $newOrd): self
  784.     {
  785.         $oldOrd $this->ord;
  786.         $this->newOrd $newOrd;
  787.         $this->ord $newOrd;
  788.         $this->ordChangeDirection = ($this->newOrd $oldOrd) ? 'desc' 'asc';
  789.         return $this;
  790.     }
  791.     public function getStart(): ?\DateTimeInterface
  792.     {
  793.         return $this->start;
  794.     }
  795.     public function setStart(?\DateTimeInterface $start): self
  796.     {
  797.         $this->start $start;
  798.         return $this;
  799.     }
  800.     public function getEnd(): ?\DateTimeInterface
  801.     {
  802.         return $this->end;
  803.     }
  804.     public function setEnd(?\DateTimeInterface $end): self
  805.     {
  806.         $this->end $end;
  807.         return $this;
  808.     }
  809.     public function getReminderBefore(): ?int
  810.     {
  811.         return $this->reminderBefore;
  812.     }
  813.     public function setReminderBefore(?int $reminderBefore): self
  814.     {
  815.         $this->reminderBefore $reminderBefore;
  816.         return $this;
  817.     }
  818.     public function getReminderAfter(): ?int
  819.     {
  820.         return $this->reminderAfter;
  821.     }
  822.     public function setReminderAfter(?int $reminderAfter): self
  823.     {
  824.         $this->reminderAfter $reminderAfter;
  825.         return $this;
  826.     }
  827.     public function getIsReminderBefore(): ?bool
  828.     {
  829.         return $this->isReminderBefore;
  830.     }
  831.     public function setIsReminderBefore(?bool $isReminderBefore): self
  832.     {
  833.         $this->isReminderBefore $isReminderBefore;
  834.         return $this;
  835.     }
  836.     public function getIsReminderAfter(): ?bool
  837.     {
  838.         return $this->isReminderAfter;
  839.     }
  840.     public function setIsReminderAfter(?bool $isReminderAfter): self
  841.     {
  842.         $this->isReminderAfter $isReminderAfter;
  843.         return $this;
  844.     }
  845.     public function getIsAllowRandom(): ?bool
  846.     {
  847.         return $this->isAllowRandom;
  848.     }
  849.     public function setIsAllowRandom(?bool $isAllowRandom): self
  850.     {
  851.         $this->isAllowRandom $isAllowRandom;
  852.         return $this;
  853.     }
  854.     public function getParentCourse()
  855.     {
  856.         return $this->elCourseAlways;
  857.     }
  858.     public function getForIndex()
  859.     {
  860.         $translations = [];
  861.         foreach ($this->getTranslations() as $translation) {
  862.             $translations[] = [
  863.                 $translation->getLocale() => [
  864.                     'title' => $translation->getTitle()
  865.                 ]
  866.             ];
  867.         }
  868.         $data = [
  869.             'id' => $this->getId(),
  870.             'ord' => $this->getOrd(),
  871.             'examLevel' => $this->getExamLevel(),
  872.             'duration' => $this->getDuration(),
  873.             'isConsiderForPass' => $this->getIsConsiderForPass(),
  874.             'elCourseAlways' => $this->getElCourseAlways()->getId(),
  875.         ];
  876.         $userGroups = [];
  877.         foreach ($this->getUserGroups() as $ug) {
  878.             $userGroups[] = $ug->getId();
  879.         }
  880.         $data['userGroups'] = $userGroups;
  881.         if ($this->getElTask()) {
  882.             $data['elTask'] = $this->getElTask()->getId();
  883.         }
  884.         if ($this->getElLesstionTopic()) {
  885.             $data['elLesstionTopic'] = $this->getElLesstionTopic()->getId();
  886.         }
  887.         if ($this->getElLession()) {
  888.             $data['elLession'] = $this->getElLession()->getId();
  889.         }
  890.         if ($this->getElCourse()) {
  891.             $data['elCourse'] = $this->getElCourse()->getId();
  892.         }
  893.         $data['translations'] = $translations;
  894.         return $data;
  895.     }
  896.     /**
  897.      * @return Collection|CommonComment[]
  898.      */
  899.     public function getCommonComments(): Collection
  900.     {
  901.         return $this->commonComments;
  902.     }
  903.     public function addCommonComment(CommonComment $commonComment): self
  904.     {
  905.         if (!$this->commonComments->contains($commonComment)) {
  906.             $this->commonComments[] = $commonComment;
  907.             $commonComment->setElExam($this);
  908.         }
  909.         return $this;
  910.     }
  911.     public function removeCommonComment(CommonComment $commonComment): self
  912.     {
  913.         if ($this->commonComments->removeElement($commonComment)) {
  914.             // set the owning side to null (unless already changed)
  915.             if ($commonComment->getElExam() === $this) {
  916.                 $commonComment->setElExam(null);
  917.             }
  918.         }
  919.         return $this;
  920.     }
  921.     public function getIsPostEnable()
  922.     {
  923.         return true;
  924.     }
  925.     public function getPostText()
  926.     {
  927.         $postText = [];
  928.         foreach ($this->getTranslations() as $translation) {
  929.             $postText[] = $translation->getTitle();
  930.         }
  931.         return implode('###'$postText);
  932.     }
  933.     public function getPostPoster()
  934.     {
  935.         return '';
  936.     }
  937.     public function getMetadataTranslation()
  938.     {
  939.         $translations = [];
  940.         foreach ($this->getTranslations() as $translation) {
  941.             $translations[] = [
  942.                 $translation->getLocale() => [
  943.                     'title' => $translation->getTitle(),
  944.                     'description' => $translation->getDescription()
  945.                 ]
  946.             ];
  947.         }
  948.         return $translations;
  949.     }
  950.     public function getPostMetadata()
  951.     {
  952.         $metadata = [
  953.             'elExam' => [
  954.                 'id' => $this->getId(),
  955.                 'translations' => $this->getMetadataTranslation(),
  956.                 'examLevel' => $this->getExamLevel(),
  957.                 'tags' => $this->getTagsArray()
  958.             ],
  959.             'elCourseAlways' => [
  960.                 'id' => $this->getElCourseAlways()->getId(),
  961.                 'translations' => $this->getElCourseAlways()->getMetadataTranslation(),
  962.                 'elCourseCategory' => $this->getElCourseAlways()->getElCourseCategory() ? $this->getElCourseAlways()->getElCourseCategory()->getMeta() : null,
  963.             ]
  964.         ];
  965.         switch ($this->getExamLevel()) {
  966.             case self::EXAMLEVEL_LESSIONTOPIC:
  967.                 $metadata['elLessionTopic'] = [
  968.                     'id' => $this->getElLessionTopic()->getId(),
  969.                     'translations' => $this->getElLessionTopic()->getMetadataTranslation()
  970.                 ];
  971.                 break;
  972.             case self::EXAMLEVEL_LESSION:
  973.                 $metadata['elLession'] = [
  974.                     'id' => $this->getElLession()->getId(),
  975.                     'translations' => $this->getElLession()->getMetadataTranslation()
  976.                 ];
  977.                 break;
  978.             case self::EXAMLEVEL_TASK:
  979.                 $metadata['elTask'] = [
  980.                     'id' => $this->getElTask()->getId(),
  981.                     'translations' => $this->getElTask()->getMetadataTranslation()
  982.                 ];
  983.                 break;
  984.         }
  985.         return $metadata;
  986.     }
  987.     public function getPostUserGroups()
  988.     {
  989.         return $this->getUserGroups();
  990.     }
  991.     public function getPostSource()
  992.     {
  993.         return CommonComment::SOURCE_ELEXAM;
  994.     }
  995.     public function getPostSubSource()
  996.     {
  997.         return '';
  998.     }
  999.     public function getIsCommentEnable(): ?bool
  1000.     {
  1001.         return $this->isCommentEnable;
  1002.     }
  1003.     public function setIsCommentEnable(?bool $isCommentEnable): self
  1004.     {
  1005.         $this->isCommentEnable $isCommentEnable;
  1006.         return $this;
  1007.     }
  1008.     public function getIsReviewEnable(): ?bool
  1009.     {
  1010.         return $this->isReviewEnable;
  1011.     }
  1012.     public function setIsReviewEnable(?bool $isReviewEnable): self
  1013.     {
  1014.         $this->isReviewEnable $isReviewEnable;
  1015.         return $this;
  1016.     }
  1017.     public function getIsShowPoints(): ?bool
  1018.     {
  1019.         return $this->isShowPoints;
  1020.     }
  1021.     public function setIsShowPoints(?bool $isShowPoints): self
  1022.     {
  1023.         $this->isShowPoints $isShowPoints;
  1024.         return $this;
  1025.     }
  1026.     public function getCloneId()
  1027.     {
  1028.         return $this->cloneId;
  1029.     }
  1030.     public function setCloneId($cloneId)
  1031.     {
  1032.         $this->cloneId $cloneId;
  1033.         return $this;
  1034.     }
  1035.     /**
  1036.      * @return Collection<int, UserGroup>
  1037.      */
  1038.     public function getUserGroups(): Collection
  1039.     {
  1040.         return $this->userGroups;
  1041.     }
  1042.     public function addUserGroup(UserGroup $userGroup): self
  1043.     {
  1044.         if (!$this->userGroups->contains($userGroup)) {
  1045.             $this->userGroups[] = $userGroup;
  1046.         }
  1047.         return $this;
  1048.     }
  1049.     public function removeUserGroup(UserGroup $userGroup): self
  1050.     {
  1051.         $this->userGroups->removeElement($userGroup);
  1052.         return $this;
  1053.     }
  1054.     public function removeAllUserGroups(): self
  1055.     {
  1056.         foreach ($this->userGroups as $userGroup) {
  1057.             $this->removeUserGroup($userGroup);
  1058.         }
  1059.         return $this;
  1060.     }
  1061.     public function getBulletPoints(): ?array
  1062.     {
  1063.         if ($this->bulletPoints === null) {
  1064.             $this->bulletPoints = [];
  1065.         }
  1066.         return $this->bulletPoints;
  1067.     }
  1068.     public function setBulletPoints(?array $bulletPoints): self
  1069.     {
  1070.         if (!is_array($bulletPoints)) {
  1071.             return $this;
  1072.         }
  1073.         $this->bulletPoints $bulletPoints;
  1074.         return $this;
  1075.     }
  1076.     public function isIsStepByStep(): ?bool
  1077.     {
  1078.         return $this->isStepByStep;
  1079.     }
  1080.     public function setIsStepByStep(?bool $isStepByStep): self
  1081.     {
  1082.         $this->isStepByStep $isStepByStep;
  1083.         return $this;
  1084.     }
  1085.     /**
  1086.      * @return Collection|SurveyTrigger[]
  1087.      */
  1088.     public function getSurveyTriggers(): Collection
  1089.     {
  1090.         return $this->surveyTriggers;
  1091.     }
  1092.     public function addSurveyTrigger(SurveyTrigger $surveyTrigger): self
  1093.     {
  1094.         if (!$this->surveyTriggers->contains($surveyTrigger)) {
  1095.             $this->surveyTriggers[] = $surveyTrigger;
  1096.             $surveyTrigger->setElExam($this);
  1097.         }
  1098.         return $this;
  1099.     }
  1100.     public function removeSurveyTrigger(SurveyTrigger $surveyTrigger): self
  1101.     {
  1102.         if ($this->surveyTriggers->removeElement($surveyTrigger)) {
  1103.             // set the owning side to null (unless already changed)
  1104.             if ($surveyTrigger->getElExam() === $this) {
  1105.                 $surveyTrigger->setElExam(null);
  1106.             }
  1107.         }
  1108.         return $this;
  1109.     }
  1110.     /**
  1111.      * @Groups({"ElExam:Read", "ElLession:Detail"})
  1112.      */
  1113.     public function isSurvey(): bool
  1114.     {
  1115.         return $this->surveyTriggers?->count() > 0;
  1116.     }
  1117.     public function getIsAutoResultSend(): ?bool
  1118.     {
  1119.         return $this->isAutoResultSend;
  1120.     }
  1121.     public function setIsAutoResultSend(?bool $isAutoResultSend): self
  1122.     {
  1123.         $this->isAutoResultSend $isAutoResultSend;
  1124.         return $this;
  1125.     }
  1126.     public function getIsOnlyChoiceQuestion(): ?bool
  1127.     {
  1128.         return $this->isOnlyChoiceQuestion;
  1129.     }
  1130.     public function setIsOnlyChoiceQuestion(?bool $isOnlyChoiceQuestion): self
  1131.     {
  1132.         $this->isOnlyChoiceQuestion $isOnlyChoiceQuestion;
  1133.         return $this;
  1134.     }
  1135.     public function getIsOnlyContinueOnPass(): ?bool
  1136.     {
  1137.         return $this->isOnlyContinueOnPass;
  1138.     }
  1139.     public function setIsOnlyContinueOnPass(?bool $isOnlyContinueOnPass): self
  1140.     {
  1141.         $this->isOnlyContinueOnPass $isOnlyContinueOnPass;
  1142.         return $this;
  1143.     }
  1144. }