<?php
declare(strict_types=1);
namespace App\Entity\Core;
use App\Controller\Admin\EasyAdmin\ProblemType;
use App\Entity\Core\Classroom\ClassroomType;
use App\Entity\Core\Topic\Topic;
use App\Entity\User\User;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\PersistentCollection;
use JsonSerializable;
#[ORM\Table('template_mathproblem')]
#[ORM\Index(name: 'difficulty_idx', columns: ['difficulty'])]
#[ORM\Index(name: 'type_idx', columns: ['type'])]
#[ORM\Entity(repositoryClass: TemplateMathproblemRepository::class)]
class TemplateMathproblem implements JsonSerializable
{
// types used in database
public const int TYPE_RADIO_BUTTON = 0;
public const int TYPE_NUMBER = 1;
public const int TYPE_DRAG_AND_DROP = 4;
public const int TYPE_FORMULA = 5;
public const int TYPE_DROPDOWN = 6;
public const int TYPE_WORD_OPTIONS = 7;
public const int TYPE_TEXT = 8;
public const int TYPE_PARAGRAPH = 9;
public const int TYPE_MARK = 10;
public const int TEMPLATE_MATH_PROBLEM_TABLE = 11;
public const int TEMPLATE_MATH_PROBLEM_GRID = 12;
public const array TEMPLATE_MATH_PROBLEM_TYPES = [
self::TYPE_RADIO_BUTTON,
self::TYPE_NUMBER,
self::TYPE_DRAG_AND_DROP,
self::TYPE_FORMULA,
self::TYPE_DROPDOWN,
self::TYPE_WORD_OPTIONS,
self::TYPE_TEXT,
self::TYPE_PARAGRAPH,
self::TYPE_MARK
];
#[ORM\Column(name: 'id', type: 'integer')]
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'AUTO')]
private ?int $id = null; // RSM: This seems to work for both Doctrine and EasyAdmin, might have to remove the typehint if more issues pop up though.
#[ORM\ManyToOne(targetEntity: User::class)]
private ?User $creator = null;
#[ORM\Column(name: 'is_help_allowed', type: 'boolean')]
private bool $helpAllowed;
#[ORM\Column(name: 'difficulty', type: 'smallint')]
private int $difficulty;
/**
* Specifies the type of problem:<br>
* 0 = single choice, multiple available answers<br>
* 1 = single choice, text answer<br>
* 4 = Drag and Drop
*/
#[ORM\Column(name: 'type', type: 'smallint')]
private int $type;
#[ORM\Column(name: 'is_unique', type: 'boolean', unique: false)]
private bool $unique;
#[ORM\Column(name: 'has_priority', type: 'boolean', unique: false)]
private bool $priority;
#[ORM\Column(name: 'is_valid', type: 'boolean', unique: false, options: ['default' => true])]
private bool $valid;
/**
* The mathproblems that are created using this template
*
* @var Collection|ArrayCollection|Mathproblem[]
*/
#[ORM\OneToMany(targetEntity: Mathproblem::class, mappedBy: 'template', cascade: ['persist', 'remove'])]
private Collection|array $mathproblems;
#[ORM\JoinColumn(name: 'topic_id', referencedColumnName: 'id')]
#[ORM\ManyToOne(targetEntity: Topic::class, inversedBy: 'templates')]
private ?Topic $topic = null;
/**
* Target can be all - 0, session - 1, homework - 2, single session - 3, screening - 4
*/
#[ORM\Column(name: 'target', type: 'smallint', nullable: false)]
private int $target;
/**
* @var ArrayCollection|TagMathproblem[]
*/
#[ORM\JoinTable(name: 'relation_template_tag')]
#[ORM\JoinColumn(name: 'mpt_tag_id', referencedColumnName: 'id')]
#[ORM\ManyToMany(targetEntity: TagMathproblem::class, inversedBy: 'templates')]
private array|Collection $tags;
#[ORM\Column(name: 'mptopic', type: 'string', nullable: true)]
private ?string $mptopic = null;
/**
* Mathproblem solving time in minutes
*/
#[ORM\Column(name: 'duration', type: 'smallint')]
private int $duration;
/**
* @var ArrayCollection|TemplateSet[]
*
*/
#[ORM\ManyToMany(targetEntity: TemplateSet::class, mappedBy: 'templates')]
private array|Collection|PersistentCollection $templateSets;
/**
* @var Collection|ArrayCollection|ClassroomType[]
*/
#[ORM\ManyToMany(targetEntity: ClassroomType::class)]
#[ORM\JoinTable(name: 'template_excluded_classroomtypes')]
#[ORM\JoinColumn(name: 'template_id', referencedColumnName: 'id')]
#[ORM\InverseJoinColumn(name: 'classroomtype_id', referencedColumnName: 'id')]
private Collection $excludedClassroomTypes;
#[ORM\Column(name: 'use_for_worksheet', type: 'boolean', options: ['default' => true])]
private bool $useForWorksheet = true;
#[ORM\Column(name: 'use_compact_version', type: 'boolean', options: ['default' => false])]
private bool $useCompactVersion = false;
#[ORM\Column(name: 'should_shuffle', type: 'boolean', options: ['default' => true])]
private bool $shouldShuffle = true;
#[ORM\Column(name: 'ignore_case', type: 'boolean', options: ['default' => false])]
private bool $ignoreCase = false;
/**
* Flag used to count number of valid template mathproblems
*/
private int $mathproblemsCount = 0;
#[ORM\Column(name: 'answer_position_vertical', type: 'boolean', options: ['default' => false])]
private bool $answerPositionVertical;
/**
* For the moment type is 4 for both match, block and sort problems. This field is used to differentiate.
*/
#[ORM\Column(name: 'dnd_type', type: 'string', nullable: true)]
private ?string $dndType;
#[ORM\Column(name: 'deleted_at', type: 'datetime', nullable: true)]
private ?DateTime $deletedAt;
/**
* TemplateMathproblem constructor.
*/
public function __construct()
{
$this->mathproblems = new ArrayCollection();
$this->tags = new ArrayCollection();
$this->templateSets = new ArrayCollection();
$this->excludedClassroomTypes = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
/**
* @return Collection|ArrayCollection|Mathproblem[]
*/
public function getMathproblems(): Collection
{
return $this->mathproblems;
}
public function addMathproblem(Mathproblem $mathproblem): TemplateMathproblem
{
$this->mathproblems->add($mathproblem);
return $this;
}
public function removeMathproblem(Mathproblem $mathproblem): bool
{
return $this->mathproblems->removeElement($mathproblem);
}
public function getTopic(): ?Topic
{
return $this->topic;
}
public function setTopic(?Topic $topic): void
{
$this->topic = $topic;
}
public function getDifficulty(): int
{
return $this->difficulty;
}
public function setDifficulty(int $difficulty) : void
{
$this->difficulty = $difficulty;
}
public function getType(): int
{
return $this->type;
}
public function setType(int $type): void
{
$this->type = $type;
}
public function getTags(): Collection
{
return $this->tags;
}
public function addTag(TagMathproblem $tag): void
{
$this->tags->add($tag);
}
/**
* @return Collection|ArrayCollection|ClassroomType[]
*/
public function getExcludedClassroomTypes(): Collection
{
return $this->excludedClassroomTypes;
}
public function addExcludedClassroomType(ClassroomType $classroomType): self
{
if (!$this->excludedClassroomTypes->contains($classroomType)) {
$this->excludedClassroomTypes->add($classroomType);
}
return $this;
}
public function removeExcludedClassroomType(ClassroomType $classroomType): bool
{
return $this->excludedClassroomTypes->removeElement($classroomType);
}
public function getValidTagArray(): array {
$tagList = [];
foreach ($this->tags as $tag) {
if ($tag->isEnabled()) {
$tagList[] = $tag->getName();
}
}
return $tagList;
}
public function getTagList(): string {
$tagArray = $this->getValidTagArray();
if (empty($tagArray)) {
return '-';
}
return implode(', ', $tagArray);
}
public function getMpTopic(): ?string
{
return $this->mptopic;
}
public function setMpTopic(?string $mpTopic): void
{
$this->mptopic = $mpTopic;
}
public function isHelpAllowed(): bool
{
return $this->helpAllowed;
}
public function setHelpAllowed(bool $isAllowed): void
{
$this->helpAllowed = $isAllowed;
}
public function getTarget(): int
{
return $this->target;
}
public function setTarget(int $target): void
{
$this->target = $target;
}
public function isUnique(): bool
{
return $this->unique;
}
public function setUnique(bool $isUnique): void
{
$this->unique = $isUnique;
}
public function isValid(): bool
{
return $this->valid;
}
public function setValid(bool $valid): void
{
$this->valid = $valid;
}
public function getDuration(): int
{
return $this->duration;
}
public function setDuration(int $duration): TemplateMathproblem
{
$this->duration = $duration;
return $this;
}
public function getCreator(): ?User
{
return $this->creator;
}
public function setCreator(?User $creator): void
{
$this->creator = $creator;
}
public function isPriority(): bool
{
return $this->priority;
}
public function setPriority(bool $priority): void
{
$this->priority = $priority;
}
public function getTemplateSets(): array|ArrayCollection|PersistentCollection
{
return $this->templateSets;
}
public function addTemplateSet(TemplateSet $templateSet): void
{
if (!$this->templateSets->contains($templateSet)) {
$this->templateSets->add($templateSet);
$templateSet->addTemplate($this);
}
}
/**
* @param TemplateSet[]|ArrayCollection $templateSets
*/
public function setTemplateSets(array $templateSets): void
{
$this->templateSets = $templateSets;
}
public function isUseForWorksheet(): bool
{
return $this->useForWorksheet;
}
public function setUseForWorksheet(bool $useForWorksheet): void
{
$this->useForWorksheet = $useForWorksheet;
}
public function getUseCompactVersion(): bool
{
return $this->useCompactVersion;
}
public function setUseCompactVersion(bool $useCompactVersion): void
{
$this->useCompactVersion = $useCompactVersion;
}
public function getShouldShuffle(): bool
{
return $this->shouldShuffle;
}
public function setShouldShuffle(bool $shouldShuffle): void
{
$this->shouldShuffle = $shouldShuffle;
}
public function getIgnoreCase(): bool
{
return $this->ignoreCase;
}
public function setIgnoreCase(bool $ignoreCase): void
{
$this->ignoreCase = $ignoreCase;
}
/**
*
*/
public function setMathproblemsCount()
{
$count = 0;
/** @var Mathproblem $mathproblem */
foreach ($this->mathproblems as $mathproblem) {
if ($mathproblem->isPublished()) {
$count++;
}
}
$this->mathproblemsCount = $count;
}
public function areAllProblemsPublished(): bool
{
foreach ($this->mathproblems as $mathproblem) {
if (!$mathproblem->isPublished() && !$mathproblem->isDeleted()) {
return false;
}
}
return true;
}
public function getMathproblemsCount(): int
{
return $this->mathproblemsCount;
}
public function isAnswerPositionVertical(): bool
{
return $this->answerPositionVertical;
}
public function setAnswerPositionVertical(bool $answerPositionVertical): void
{
$this->answerPositionVertical = $answerPositionVertical;
}
public function __toString(): string
{
return (string)$this->id;
}
public function getDndType(): ?string
{
return $this->dndType ?? null;
}
public function setDndType(?string $dndType): void
{
$this->dndType = $dndType;
}
public function getProblemTypeAsString(): string {
return ProblemType::getProblemTypeFromTemplate($this)->name();
}
public function getProblemType(): ProblemType
{
return ProblemType::getProblemTypeFromTemplate($this);
}
public function getDeletedAt(): ?DateTime
{
return $this->deletedAt;
}
public function setDeletedAt(?DateTime $deletedAt): void
{
$this->deletedAt = $deletedAt;
}
function jsonSerialize(): mixed
{
return [
"id" => $this->getId(),
"type" => $this->getType(),
"topic" => $this->getTopic(),
"mpTopic" => $this->getMpTopic(),
"difficulty" => $this->getDifficulty(),
"helpAllowed" => $this->isHelpAllowed(),
"tags" => $this->getTags()->toArray(),
"duration" => $this->getDuration(),
"shouldShuffle" => $this->getShouldShuffle(),
"useCompactVersion" => $this->getUseCompactVersion(),
"answerPositionVertical" => $this->isAnswerPositionVertical(),
"templateSets" => $this->getTemplateSets()->toArray(),
"mathproblemCount" => $this->getMathproblemsCount(),
"creator" => $this->getCreator(),
"ignoreCase" => $this->getIgnoreCase(),
"target" => $this->getTarget(),
];
}
}