<?php
namespace App\Entity\Training;
use ApiPlatform\Metadata\ApiResource;
use App\Entity\Schoolyear;
use App\Repository\Training\ScheduleRepository;
use App\Traits\Actions;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ScheduleRepository::class)]
#[ORM\Table(name: 'hs_tc_training_schedule')]
#[ApiResource]
class Schedule
{
use Actions;
#[ORM\ManyToOne(inversedBy: 'schedules')]
#[ORM\JoinColumn(nullable: false)]
private ?Groupe $groupe = null;
#[ORM\Column]
private ?string $semester = null;
#[ORM\Column(nullable: true)]
private ?\DateTimeImmutable $startAt = null;
#[ORM\Column(nullable: true)]
private ?\DateTimeImmutable $endAt = null;
#[ORM\OneToMany(mappedBy: 'schedule', targetEntity: Scheduleitem::class, orphanRemoval: true)]
#[ORM\OrderBy(["day" => "ASC", "startAt" => "ASC"])]
private Collection $scheduleitems;
#[ORM\OneToMany(mappedBy: 'schedule', targetEntity: Scheduleevent::class, orphanRemoval: true)]
#[ORM\OrderBy(["takesplaceOn" => "ASC", "startAt" => "ASC"])]
private Collection $scheduleevents;
#[ORM\Column(length: 255)]
private ?string $slug = null;
public function __construct()
{
// date_default_timezone_set('Africa/Casablanca');
$this->createAt=new \DateTime('now');
$this->published=true;
$this->scheduleitems = new ArrayCollection();
$this->slug=uniqid("schedule-");
}
public function getGroupe(): ?Groupe
{
return $this->groupe;
}
public function setGroupe(?Groupe $groupe): self
{
$this->groupe = $groupe;
return $this;
}
public function getSemester(): ?string
{
return $this->semester;
}
public function setSemester(?string $semester): void
{
$this->semester = $semester;
}
public function getStartAt(): ?\DateTimeImmutable
{
return $this->startAt;
}
public function setStartAt(?\DateTimeImmutable $startAt): self
{
$this->startAt = $startAt;
return $this;
}
public function getEndAt(): ?\DateTimeImmutable
{
return $this->endAt;
}
public function setEndAt(?\DateTimeImmutable $endAt): self
{
$this->endAt = $endAt;
return $this;
}
/**
* @return Collection<int, Scheduleitem>
*/
public function getScheduleitems(): Collection
{
return $this->scheduleitems;
}
public function addScheduleitem(Scheduleitem $scheduleitem): self
{
if (!$this->scheduleitems->contains($scheduleitem)) {
$this->scheduleitems->add($scheduleitem);
$scheduleitem->setSchedule($this);
}
return $this;
}
public function removeScheduleitem(Scheduleitem $scheduleitem): self
{
if ($this->scheduleitems->removeElement($scheduleitem)) {
// set the owning side to null (unless already changed)
if ($scheduleitem->getSchedule() === $this) {
$scheduleitem->setSchedule(null);
}
}
return $this;
}
/**
* @return Collection<int, Scheduleevent>
*/
public function getScheduleevents(): Collection
{
return $this->scheduleevents;
}
public function addScheduleevent(Scheduleevent $scheduleevent): self
{
if (!$this->scheduleevents->contains($scheduleevent)) {
$this->scheduleevents->add($scheduleevent);
$scheduleevent->setSchedule($this);
}
return $this;
}
public function removeScheduleevent(Scheduleevent $scheduleevent): self
{
if ($this->scheduleevents->removeElement($scheduleevent)) {
// set the owning side to null (unless already changed)
if ($scheduleevent->getSchedule() === $this) {
$scheduleevent->setSchedule(null);
}
}
return $this;
}
public function getSlug()
{
return $this->slug;
}
public function setSlug($slug)
{
$this->slug = $slug;
}
function getDayName($dayNumber) {
// Vérifie si le jour est entre 1 et 7
if ($dayNumber < 1 || $dayNumber > 7) {
return "Jour invalide";
}
// Utilise strftime() pour obtenir le nom du jour en français
setlocale(LC_TIME, 'fr_FR.utf8'); // Configuration de la localisation en français
return strftime('%A', strtotime("Sunday +{$dayNumber} days"));
}
public function isCurrent(): bool
{
$today = new \DateTime(); // Crée un objet DateTime représentant aujourd'hui
// Vérifie si la date d'aujourd'hui est entre startAt et endAt
return $today >= $this->startAt && $today <= $this->endAt;
}
public function __toString(){
return $this->getStartAt()->format('d/m/Y').' - '.$this->getEndAt()->format('d/m/Y');
}
public function getScheduleItemsDay(int $day)
{
$items=new ArrayCollection();
foreach ($this->scheduleitems as $item){
if($item->getDay()== $day) $items->add($item);
}
return $items;
}
public function getScheduleEventsDay(int $day)
{
$items=new ArrayCollection();
foreach ($this->scheduleevents as $item){
if($item->getDay()== $day) $items->add($item);
}
return $items;
}
public function getLevel(){
return match ($this->semester) {
'Semester 2', 'Semester 1' => '1ère année',
'Semester 3', 'Semester 4' => '2ème année',
'Semester 5', 'Semester 6' => '3ème année',
default => '',
};
}
public function getWeeks()
{
$startAt=$this->getStartAt();
$endAt=$this->getEndAt();
$weeks = [];
$currentStart = $startAt; // Pas besoin de clone car DateTimeImmutable est immuable
while ($currentStart <= $endAt) {
// Calculer la fin de la semaine (jusqu'à samedi ou endAt)
$currentEnd = $currentStart->modify('next saturday');
// Si la date de fin dépasse la vraie date de fin (endAt), on ajuste
if ($currentEnd > $endAt) {
$currentEnd = $endAt;
}
// Ajouter la période dans le tableau des semaines
$weeks[] = [
'startAt' => $currentStart,
'endAt' => $currentEnd
];
// Passer à la semaine suivante (lundi)
$currentStart = $currentEnd->modify('+2 day');
}
return $weeks;
}
public function getMonths(): array
{
$startAt=$this->getStartAt();
$endAt=$this->getEndAt();
$months = [];
$currentStart = $startAt;
while ($currentStart <= $endAt) {
// Déterminer le dernier jour du mois en cours
$currentEnd = $currentStart->modify('last day of this month');
// Si le dernier jour calculé dépasse la date de fin (endAt), on ajuste
if ($currentEnd > $endAt) {
$currentEnd = $endAt;
}
// Ajouter la période dans le tableau des mois
$months[] = [
'startAt' => $currentStart,
'endAt' => $currentEnd
];
// Passer au premier jour du mois suivant
$currentStart = $currentStart->modify('first day of next month');
}
return $months;
}
public function getSeances()
{
$allSeances = [];
// Parcourir chaque ScheduleItem
foreach ($this->getScheduleItems() as $scheduleItem) {
// Ajouter chaque séance de ScheduleItem à la collection $allSeances
foreach ($scheduleItem->getSeances() as $seance) {
$allSeances[]=$seance;
}
}
usort($allSeances, function($a, $b) {
$dateA = DateTime::createFromFormat('d-m-Y H:i', $a->getTakesplaceOn()->format('d-m-Y').' '.$a->getStartAt());
$dateB = DateTime::createFromFormat('d-m-Y H:i', $b->getTakesplaceOn()->format('d-m-Y').' '.$b->getStartAt());
return $dateA <=> $dateB;
});
return $allSeances;
}
public function getSeancesCancelled()
{
$allSeances = [];
foreach ($this->getScheduleItems() as $scheduleItem) {
foreach ($scheduleItem->getSeancesCancelled() as $seance ) {
$allSeances[] = ['scheduleitem'=>$scheduleItem, 'seanceDate'=>$seance];
}
}
usort($allSeances, function($a, $b) {
$dateA = DateTime::createFromFormat('d-m-Y H:i', $a['seanceDate'].' '.$a['scheduleitem']->getStartAt());
$dateB = DateTime::createFromFormat('d-m-Y H:i', $b['seanceDate'].' '.$b['scheduleitem']->getStartAt());
return $dateA <=> $dateB;
});
return $allSeances;
}
public function getSeancesNotCreate()
{
$allSeances = [];
foreach ($this->getScheduleItems() as $scheduleItem) {
foreach ($scheduleItem->getSeancesNotCreate() as $seance ) {
$allSeances[] = ['scheduleitem'=>$scheduleItem, 'seanceDate'=>$seance];
}
}
usort($allSeances, function($a, $b) {
$dateA = DateTime::createFromFormat('d-m-Y H:i', $a['seanceDate'].' '.$a['scheduleitem']->getStartAt());
$dateB = DateTime::createFromFormat('d-m-Y H:i', $b['seanceDate'].' '.$b['scheduleitem']->getStartAt());
return $dateA <=> $dateB;
});
return $allSeances;
}
public function isWeekly(): bool
{
if ($this->startAt === null || $this->endAt === null) {
return false; // Si une des deux dates est absente, on considère que ce n'est pas une période valide.
}
// Calcul de la différence entre les deux dates
$interval = $this->startAt->diff($this->endAt);
// Vérifier si la différence est inférieure ou égale à 7 jours
return $interval->days <= 7;
}
}