<?php
namespace App\Entity\Formation;
use _PHPStan_a3459023a\Nette\Utils\DateTime;
use ApiPlatform\Metadata\ApiResource;
use App\Repository\Formation\TimetableitemRepository;
use App\Traits\Actions;
use DateInterval;
use DatePeriod;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use InvalidArgumentException;
#[ORM\Entity(repositoryClass: TimetableitemRepository::class)]
#[ApiResource]
#[ORM\Table(name: 'hs_tc_formation_timetableitem')]
class Timetableitem
{
use Actions;
#[ORM\ManyToOne(inversedBy: 'timetableitems')]
#[ORM\JoinColumn(nullable: false)]
private ?Timetable $timetable = null;
#[ORM\ManyToOne(inversedBy: 'timetableitems')]
#[ORM\JoinColumn(nullable: false)]
private ?Attribution $attribution = null;
#[ORM\Column(length: 255)]
private ?string $day = null;
#[ORM\Column(length: 255)]
private ?string $startAt = null;
#[ORM\Column(nullable: true)]
private ?string $length = null;
#[ORM\Column(nullable: true)]
private ?string $salle = null;
#[ORM\Column(nullable: true)]
private ?string $nature = null;
#[ORM\OneToMany(mappedBy: 'timetableitem', targetEntity: Aseance::class, orphanRemoval: true)]
private Collection $aseances;
#[ORM\Column(type: "json", nullable: true)]
private ?array $seancesCancelled=[];
public function __construct()
{
// date_default_timezone_set('Africa/Casablanca');
$this->createAt=new \DateTime('now');
$this->published=true;
$this->aseances = new ArrayCollection();
}
public function getTimetable(): ?Timetable
{
return $this->timetable;
}
public function setTimetable(?Timetable $timetable): self
{
$this->timetable = $timetable;
return $this;
}
public function getAttribution(): ?Attribution
{
return $this->attribution;
}
public function setAttribution(?Attribution $attribution): self
{
$this->attribution = $attribution;
return $this;
}
public function getDay(): ?string
{
return $this->day;
}
public function setDay(string $day): self
{
$this->day = $day;
return $this;
}
public function getStartAt(): ?string
{
return $this->startAt;
}
public function setStartAt(?string $startAt): void
{
$this->startAt = $startAt;
}
public function getLength(): ?string
{
return $this->length;
}
public function setLength(?string $length): self
{
$this->length = $length;
return $this;
}
/**
* @throws \Exception
*/
function getLengthAsDateInterval()
{
// Regex pour capturer les heures et les minutes
$pattern = '/^(?:(\d+)h)?(?:\s*(\d+)min)?$/';
if (preg_match($pattern, $this->getLength(), $matches)) {
$hours = isset($matches[1]) ? (int)$matches[1] : 0;
$minutes = isset($matches[2]) ? (int)$matches[2] : 0;
// Création de l'objet DateInterval
$intervalSpec = sprintf('PT%dH%dM', $hours, $minutes);
return new DateInterval($intervalSpec);
} else {
throw new InvalidArgumentException("Invalid time string format: $this->length");
}
}
function getLengthAsSeconds() {
return ($this->getLengthAsDateInterval()->y * 365 * 24 * 60 * 60) +
($this->getLengthAsDateInterval()->m * 30 * 24 * 60 * 60) +
($this->getLengthAsDateInterval()->d * 24 * 60 * 60) +
($this->getLengthAsDateInterval()->h * 60 * 60) +
($this->getLengthAsDateInterval()->i * 60) +
$this->getLengthAsDateInterval()->s;
}
/**
* @throws \Exception
*/
function getLengthAsStr()
{
return $this->getLengthAsDateInterval()->format('%hh%imin');
}
function getIntervalAsStr($interval)
{
return $interval->format('%h h %i min');
}
/**
* @return Collection<int, Aseance>
*/
public function getAseances(): Collection
{
return $this->aseances;
}
public function addAseance(Aseance $aseance): self
{
if (!$this->aseances->contains($aseance)) {
$this->aseances->add($aseance);
$aseance->setTimetableitem($this);
}
return $this;
}
public function removeAseance(Aseance $aseance): self
{
if ($this->aseances->removeElement($aseance)) {
// set the owning side to null (unless already changed)
if ($aseance->getTimetableitem() === $this) {
$aseance->setTimetableitem(null);
}
}
return $this;
}
public function getSalle(): ?string
{
return $this->salle;
}
public function setSalle(?string $salle): void
{
$this->salle = $salle;
}
public function getNature(): ?string
{
return $this->nature;
}
public function setNature(?string $nature): void
{
$this->nature = $nature;
}
public function getSeancesCancelled(): array
{
return $this->seancesCancelled!=null?$this->seancesCancelled:[];
}
public function setSeancesCancelled(array $seancesCancelled): void
{
$this->seancesCancelled = $seancesCancelled;
}
public function addDate(\DateTimeInterface $date): self
{
if($this->seancesCancelled==null) $this->seancesCancelled=[];
if (!in_array($date->format('d-m-Y'), array_map(fn($d) => $d, $this->seancesCancelled))) {
$this->seancesCancelled[] = $date->format('d-m-Y');
}
return $this;
}
public function removeDate(\DateTimeInterface $date): self
{
$formattedDate = $date->format('d-m-Y');
$this->seancesCancelled = array_filter(
$this->seancesCancelled,
fn($d) => $d !== $formattedDate
);
$this->seancesCancelled = array_values($this->seancesCancelled);
return $this;
}
public function hasDate(\DateTimeInterface $date): bool
{
if($this->seancesCancelled==null) $this->seancesCancelled=[];
foreach ($this->seancesCancelled as $d) {
if ($d === $date->format('d-m-Y')) {
return true;
}
}
return false;
}
public function getStartAt100()
{
$dayAsSeconds = 15*60*60;
//$now= new \DateTime();
//$date1=DateTime::createFromFormat('d-m-Y H:i', $now->format('d-m-Y'.' 08:00'));
//$date2=DateTime::createFromFormat('d-m-Y H:i', $now->format('d-m-Y'.' '.$this->getStartAt()));
//return ($date2->diff($date1)->h*60*60+$date2->diff($date1)->i*60)/$dayAsSeconds*100;
$time=explode(':',$this->getStartAt());
$h=(intval($time[0])-8)*60*60;
$min=intval($time[1])*60;
return ($h+$min)/$dayAsSeconds*100;
//return $date1->format('H:i');
}
public function getLength100(): float
{
$dayAsSeconds = 15*60*60;
return $this->getLengthAsSeconds()/$dayAsSeconds*100;
}
public function getStartAtPx()
{
// $infos=explode(":",$this->getStartAt());
// return intval($infos[0])-8+($infos[1] == "30" ? 0.5 : ($infos[1] == "15" ? 0.25 : 0));
$infos = explode(":", $this->getStartAt());
$hours = intval($infos[0]);
$minutes = intval($infos[1]);
// Convertir les minutes en fraction d'heure
$minutesFraction = $minutes / 60;
// Calculer la valeur totale en heures décimales
$totalHours = ($hours - 8) + $minutesFraction;
return $totalHours;
}
public function getLengthAtPx()
{
$pattern = '/^(?:(\d+)h)?(?:\s*(\d+)min)?$/';
preg_match($pattern, $this->getLength(), $matches);
$hours = isset($matches[1]) ? (int)$matches[1] : 0;
$minutes = isset($matches[2]) ? (int)$matches[2] : 0;
return $hours+$minutes/60;
}
function getDayFrench() {
$joursFrancais = [
1 => 'lundi',
2 => 'mardi',
3 => 'mercredi',
4 => 'jeudi',
5 => 'vendredi',
6 => 'samedi',
7 => 'dimanche',
];
return $joursFrancais[$this->day] ?? "Jour invalide. Veuillez entrer un nombre entre 1 et 7.";
}
public function getAseancesDate()
{
$begin = $this->timetable->getStartAt();
$end = ($this->timetable->getEndAt())->modify('+1 day');
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $end);
$days = [];
foreach ($period as $dt) {
if(intval($dt->format('N')==$this->day)){
$days[] = $dt->format('d-m-Y');
}
}
$aseances = [];
foreach ($this->aseances as $aseance) {
if(in_array($aseance->getTakesplaceOn()->format('d-m-Y'),$days)){
$aseances[] = $aseance->getTakesplaceOn()->format('d-m-Y');
}
}
return ['aseances'=>$aseances,'days'=>$days, 'presumed_aseances'=>array_diff($days,$aseances)];
}
public function getSeancesNotCreate()
{
$begin = $this->timetable->getStartAt();
$end = ($this->timetable->getEndAt())->modify('+1 day');
$now = new \DateTimeImmutable('now');
// Ajuster la fin pour ne pas dépasser la date actuelle
if ($end > $now) {
$end = $now;
}
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $end);
$days = [];
foreach ($period as $dt) {
if(intval($dt->format('N')==$this->day)){
$days[] = $dt->format('d-m-Y');
}
}
$seances = [];
foreach ($this->aseances as $seance) {
if(in_array($seance->getTakesplaceOn()->format('d-m-Y'),$days)){
$seances[] = $seance->getTakesplaceOn()->format('d-m-Y');
}
}
return array_diff($days,$seances,$this->getSeancesCancelled());
}
public function getEndAt()
{
$startAt=\DateTime::createFromFormat('d-m-Y H:i',(new \DateTime('now'))->format('d-m-Y')." ".$this->getStartAt());
$endAt=$startAt->add($this->getLengthAsDateInterval());
return $endAt->format('H:i');
}
public function getSeanceByDate($date)
{
foreach ($this->aseances as $seance) {
if($seance->getTakesplaceOn()->format('d-m-Y')==$date){
return $seance;
}
}
return null;
}
}