<?php
namespace App\Entity;
use App\Entity\Traits\Timestampable;
use App\Repository\CompetenceReferenceRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* Compétence du programme national (créée par le super-admin), rattachée à un
* SubjectReference. `quarterNumber` (1, 2 ou 3) situe la compétence dans
* l'année scolaire de façon abstraite — un SubjectReference n'est pas
* rattaché à une école donc pas à un Quarter concret ; la conversion
* "trimestre N → Quarter réel d'une école" se fait au moment de la copie
* (voir CompetenceCopier), en ordonnant les Quarter de l'année par id ASC.
*
* Copiée vers Competence (locale, par école) à la création d'un Subject issu
* de ce SubjectReference, uniquement pour les classes en système d'évaluation
* "par compétence" — cf. CompetenceCopier, calqué sur SubjectLessonCopier.
*/
#[ORM\HasLifecycleCallbacks]
#[ORM\Entity(repositoryClass: CompetenceReferenceRepository::class)]
class CompetenceReference
{
use Timestampable;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\ManyToOne(inversedBy: 'competenceReferences')]
#[ORM\JoinColumn(nullable: false)]
private ?SubjectReference $subjectReference = null;
#[ORM\Column]
private ?int $quarterNumber = null;
// Nullable : null pour une évaluation supplémentaire (evaluationOf non
// null) — son libellé est alors hérité du leader, voir getDisplayContent().
#[ORM\Column(type: 'text', nullable: true)]
private ?string $content = null;
/**
* Ordre d'affichage parmi les compétences du même trimestre.
*/
#[ORM\Column]
private ?int $position = null;
#[ORM\ManyToOne]
private ?User $author = null;
// Une même compétence évaluée plusieurs fois dans le trimestre, définie une
// fois pour toutes par le super-admin au niveau national : les écoles qui
// copient ce SubjectReference héritent directement du regroupement (voir
// CompetenceCopier), sans avoir à recréer l'évaluation supplémentaire
// elles-mêmes. Mirroir de Competence::evaluationOf (voir ce fichier pour le
// détail du principe : un seul niveau de rattachement, jamais de chaîne).
#[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'additionalEvaluations')]
#[ORM\JoinColumn(name: 'evaluation_of_id', nullable: true, onDelete: 'RESTRICT')]
private ?CompetenceReference $evaluationOf = null;
/** @var Collection<int, CompetenceReference> */
#[ORM\OneToMany(mappedBy: 'evaluationOf', targetEntity: self::class)]
private Collection $additionalEvaluations;
public function __construct()
{
$this->additionalEvaluations = new ArrayCollection();
}
public function __toString(): string
{
return $this->getDisplayContent() ?? '';
}
public function getId(): ?int
{
return $this->id;
}
public function getSubjectReference(): ?SubjectReference
{
return $this->subjectReference;
}
public function setSubjectReference(?SubjectReference $subjectReference): static
{
$this->subjectReference = $subjectReference;
return $this;
}
public function getQuarterNumber(): ?int
{
return $this->quarterNumber;
}
public function setQuarterNumber(int $quarterNumber): static
{
$this->quarterNumber = $quarterNumber;
return $this;
}
public function getContent(): ?string
{
return $this->content;
}
public function setContent(?string $content): static
{
$this->content = $content;
return $this;
}
public function getPosition(): ?int
{
return $this->position;
}
public function setPosition(int $position): static
{
$this->position = $position;
return $this;
}
public function getAuthor(): ?User
{
return $this->author;
}
public function setAuthor(?User $author): static
{
$this->author = $author;
return $this;
}
public function getEvaluationOf(): ?self
{
return $this->evaluationOf;
}
public function setEvaluationOf(?self $evaluationOf): static
{
$this->evaluationOf = $evaluationOf;
return $this;
}
/** @return Collection<int, CompetenceReference> */
public function getAdditionalEvaluations(): Collection
{
return $this->additionalEvaluations;
}
public function isAdditionalEvaluation(): bool
{
return $this->evaluationOf !== null;
}
/**
* La CompetenceReference "leader" du groupe (elle-même si autonome ou déjà
* leader). Sert de clé de regroupement à l'affichage (programme national,
* et bulletin une fois copiée en Competence — voir CompetenceCopier).
*/
public function getGroupLeader(): self
{
return $this->evaluationOf ?? $this;
}
public function getDisplayContent(): ?string
{
return $this->content ?? $this->evaluationOf?->getContent();
}
}