<?php
namespace App\Entity;
use App\Entity\Traits\TimestampableTrait;
use App\Repository\EventRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity(repositoryClass: EventRepository::class)]
/**
* @Vich\Uploadable
*/
class Event
{
use TimestampableTrait;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\Column(type: 'string', length: 255)]
private $title;
#[ORM\Column(type: 'string', length: 20)]
private $type; // 'presentiel', 'webinaire', 'hybride'
#[ORM\Column(type: 'datetime')]
private $startDate;
#[ORM\Column(type: 'datetime', nullable: true)]
private $endDate;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $location;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $visioLink;
#[ORM\Column(type: 'text')]
private $shortDescription;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $coverImage;
/**
* @Vich\UploadableField(mapping="event_images", fileNameProperty="coverImage")
* @var File|null
*/
#[Assert\Image(
maxSize: '2M',
maxSizeMessage: 'L\'image ne doit pas dépasser 2 Mo.',
mimeTypesMessage: 'Veuillez uploader une image valide (JPG, PNG, etc.).'
)]
private ?File $coverImageFile = null;
#[ORM\Column(type: 'integer', nullable: true)]
private $maxAttendees;
#[ORM\Column(type: 'string', length: 255, unique: true)]
private $slug;
#[ORM\Column(type: 'boolean')]
private $isActive = true;
#[ORM\ManyToOne(targetEntity: AccountingFirm::class, inversedBy: 'events')]
#[ORM\JoinColumn(name: 'FK_cabinet', referencedColumnName: 'id', nullable: false)]
private $accountingFirm;
#[ORM\OneToMany(mappedBy: 'event', targetEntity: EventRegistration::class, orphanRemoval: true)]
private $registrations;
#[ORM\Column(type: 'boolean')]
private $allowCompanions = false;
#[ORM\Column(type: 'array')]
private $formFields = ['nom', 'prenom', 'email', 'telephone']; // Champs par défaut
#[ORM\Column(type: 'text', nullable: true)]
private $programPoint1Description;
#[ORM\Column(type: 'text', nullable: true)]
private $programPoint2Description;
#[ORM\Column(type: 'text', nullable: true)]
private $programPoint3Description;
#[ORM\Column(type: 'text', nullable: true)]
private $programPoint4Description;
#[ORM\Column(type: 'text', nullable: true)]
private $programPoint5Description;
#[ORM\ManyToOne(targetEntity: EmailingClientCampaign::class)]
private $emailing;
public function __construct()
{
$this->registrations = new ArrayCollection();
}
// Getters and Setters...
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getType(): ?string
{
return $this->type;
}
public function setType(string $type): self
{
$this->type = $type;
return $this;
}
public function getStartDate(): ?\DateTimeInterface
{
return $this->startDate;
}
public function setStartDate(\DateTimeInterface $startDate): self
{
$this->startDate = $startDate;
return $this;
}
public function getEndDate(): ?\DateTimeInterface
{
return $this->endDate;
}
public function setEndDate(?\DateTimeInterface $endDate): self
{
$this->endDate = $endDate;
return $this;
}
public function getLocation(): ?string
{
return $this->location;
}
public function setLocation(?string $location): self
{
$this->location = $location;
return $this;
}
public function getVisioLink(): ?string
{
return $this->visioLink;
}
public function setVisioLink(?string $visioLink): self
{
$this->visioLink = $visioLink;
return $this;
}
public function getShortDescription(): ?string
{
return $this->shortDescription;
}
public function setShortDescription(string $shortDescription): self
{
$this->shortDescription = $shortDescription;
return $this;
}
public function getCoverImage(): ?string
{
return $this->coverImage;
}
public function setCoverImage(?string $coverImage): self
{
$this->coverImage = $coverImage;
return $this;
}
public function getMaxAttendees(): ?int
{
return $this->maxAttendees;
}
public function setMaxAttendees(?int $maxAttendees): self
{
$this->maxAttendees = $maxAttendees;
return $this;
}
public function getSlug(): ?string
{
return $this->slug;
}
public function setSlug(string $slug): self
{
$this->slug = $slug;
return $this;
}
public function isActive(): ?bool
{
return $this->isActive;
}
public function setIsActive(bool $isActive): self
{
$this->isActive = $isActive;
return $this;
}
public function getAccountingFirm(): ?AccountingFirm
{
return $this->accountingFirm;
}
public function setAccountingFirm(?AccountingFirm $accountingFirm): self
{
$this->accountingFirm = $accountingFirm;
return $this;
}
/**
* @return Collection<int, EventRegistration>
*/
public function getRegistrations(): Collection
{
return $this->registrations;
}
public function addRegistration(EventRegistration $registration): self
{
if (!$this->registrations->contains($registration)) {
$this->registrations[] = $registration;
$registration->setEvent($this);
}
return $this;
}
public function removeRegistration(EventRegistration $registration): self
{
if ($this->registrations->removeElement($registration)) {
// set the owning side to null (unless already changed)
if ($registration->getEvent() === $this) {
$registration->setEvent(null);
}
}
return $this;
}
public function getAllowCompanions(): ?bool
{
return $this->allowCompanions;
}
public function setAllowCompanions(bool $allowCompanions): self
{
$this->allowCompanions = $allowCompanions;
return $this;
}
public function getFormFields(): array
{
return $this->formFields;
}
public function setFormFields(array $formFields): self
{
$this->formFields = $formFields;
return $this;
}
/**
* Get remaining available spots
*/
public function getRemainingSpots(): ?int
{
if ($this->maxAttendees === null) {
return null; // unlimited
}
$totalRegistrations = 0;
foreach ($this->registrations as $registration) {
$totalRegistrations += 1 + $registration->getCompanionsCount();
}
return max(0, $this->maxAttendees - $totalRegistrations);
}
/**
* Check if event is full
*/
public function isFull(): bool
{
if ($this->maxAttendees === null) {
return false;
}
return $this->getRemainingSpots() <= 0;
}
public function setCoverImageFile(?File $coverImageFile = null): self
{
$this->coverImageFile = $coverImageFile;
if (null !== $coverImageFile) {
$this->updatedAt = new \DateTime();
}
return $this;
}
public function getCoverImageFile(): ?File
{
return $this->coverImageFile;
}
public function getProgramPoint1Description(): ?string
{
return $this->programPoint1Description;
}
public function setProgramPoint1Description(?string $programPoint1Description): self
{
$this->programPoint1Description = $programPoint1Description;
return $this;
}
public function getProgramPoint2Description(): ?string
{
return $this->programPoint2Description;
}
public function setProgramPoint2Description(?string $programPoint2Description): self
{
$this->programPoint2Description = $programPoint2Description;
return $this;
}
public function getProgramPoint3Description(): ?string
{
return $this->programPoint3Description;
}
public function setProgramPoint3Description(?string $programPoint3Description): self
{
$this->programPoint3Description = $programPoint3Description;
return $this;
}
public function getProgramPoint4Description(): ?string
{
return $this->programPoint4Description;
}
public function setProgramPoint4Description(?string $programPoint4Description): self
{
$this->programPoint4Description = $programPoint4Description;
return $this;
}
public function getProgramPoint5Description(): ?string
{
return $this->programPoint5Description;
}
public function setProgramPoint5Description(?string $programPoint5Description): self
{
$this->programPoint5Description = $programPoint5Description;
return $this;
}
/**
* Check if event is finished
*/
public function isFinished(): bool
{
$now = new \DateTime();
$eventEndDate = $this->endDate ?: $this->startDate;
return $eventEndDate < $now;
}
public function getEmailing(): ?EmailingClientCampaign
{
return $this->emailing;
}
public function setEmailing(?EmailingClientCampaign $emailing): self
{
$this->emailing = $emailing;
return $this;
}
}