<?php
namespace App\Service\Registration;
use App\Entity\ContactEmail;
use App\Entity\ContactPhone;
use App\Entity\Family;
use App\Entity\Person;
use App\Entity\Profiling;
use App\Entity\Registration;
use App\Entity\Season;
use App\Entity\Section;
use App\Entity\SectionMeta;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
//TODO: clean ce service
class Session
{
private static string $sessionKeyPrefix = 'registration_';
private SessionInterface $session;
private ?string $registrationType = 'self';
private ?Season $season = null;
private ?Family $family = null;
private ?Person $person = null;
private ?int $donation = null;
private ?Registration $registration = null;
private ?User $user = null;
/**
* @var Person[]
*/
private array $tutors = [];
private $community;
private int $step = 1;
public function __construct(private readonly EntityManagerInterface $em, RequestStack $requestStack, private readonly OrderManager $orderManager)
{
$this->session = $requestStack->getSession();
$this->init();
}
public function init()
{
$this->initRegistrationType();
$this->initSeason();
$this->initFamily();
$this->initPerson();
$this->initDonation();
$this->initRegistration();
$this->initUser();
$this->initCommunity();
$this->initTutors();
$this->step = $this->getKey('step') ?? 1;
}
public function dump($die = false): void
{
dump(
$this->getRegistrationType(),
$this->getStep(),
$this->getSeason(),
$this->getFamily(),
$this->getPerson()
);
if ($die) {
die;
}
}
public function reset($upTo = 0)
{
$this->removeKey('family');
$this->removeKey('person');
$this->removeKey('registration');
$this->removeKey('donation');
$this->removeKey('season');
$this->removeKey('registrationType');
$this->removeKey('user');
$this->removeKey('community');
$this->removeKey('step');
$this->removeKey('tutors');
}
private function getKey(string $key): mixed
{
return $this->session->get(self::$sessionKeyPrefix.$key);
}
private function setKey(string $key, $value = null): void
{
if (null === $value) {
$this->removeKey($key);
} else {
$this->session->set(self::$sessionKeyPrefix.$key, $value);
}
}
public function removeKey(string $key)
{
$this->session->remove(self::$sessionKeyPrefix.$key);
}
private function initRegistrationType()
{
$this->registrationType = $this->getKey('registrationType');
}
public function getRegistrationType(): ?string
{
return $this->registrationType;
}
public function setRegistrationType(?string $registrationType): Session
{
$this->setKey('registrationType', $registrationType);
$this->registrationType = $registrationType;
return $this;
}
private function initSeason(): void
{
$id = $this->getKey('season');
if ($id) {
$this->season = $this->em->find(Season::class, $id);
}
}
public function getSeason(): ?Season
{
return $this->season;
}
public function setSeason(?Season $season): Session
{
$id = $season?->getId();
$this->setKey('season', $id);
$this->season = $season;
return $this;
}
private function initFamily()
{
$id = $this->getKey('family');
if ($id) {
$this->family = $this->em->find(Family::class, $id);
}
return;
$this->family = $this->getKey('family');
// if (null !== ($id = $this->family?->getId())) {
// $this->family = $this->em->find(Family::class, $id);
// }
}
public function getFamily(): ?Family
{
return $this->family;
}
public function setFamily(?Family $family): Session
{
$id = $family?->getId();
$this->setKey('family', $id);
$this->family = $family;
return $this;
}
private function initPerson()
{
$id = $this->getKey('person');
if ($id) {
$this->person = $this->em->find(Person::class, $id);
}
return;
$this->person = $this->getKey('person');
if ($this->person) {
if (($contact = $this->person->getFirstEmail()) && $this->person->getFirstEmail()->getId()) {
$this->person->setFirstEmail($this->em->find(ContactEmail::class, $contact->getId()));
}
if (($contact = $this->person->getSecondEmail()) && $this->person->getSecondEmail()->getId()) {
$this->person->setSecondEmail($this->em->find(ContactEmail::class, $contact->getId()));
}
if (($contact = $this->person->getFirstPhone()) && $this->person->getFirstPhone()->getId()) {
$this->person->setFirstPhone($this->em->find(ContactPhone::class, $contact->getId()));
}
if (($contact = $this->person->getSecondPhone()) && $this->person->getSecondPhone()->getId()) {
$this->person->setSecondPhone($this->em->find(ContactPhone::class, $contact->getId()));
}
}
// if (null !== ($id = $this->person?->getId())) {
// $this->person = $this->em->find(Person::class, $id);
// }
}
public function getPerson(): ?Person
{
return $this->person;
}
public function setPerson(?Person $person): Session
{
$id = $person?->getId();
$this->setKey('person', $id);
$this->person = $person;
return $this;
}
private function initDonation()
{
$this->donation = $this->getKey('donation');
}
public function getDonation(): ?int
{
return $this->donation;
}
public function setDonation(?int $donation): Session
{
$this->setKey('donation', $donation);
$this->donation = $donation;
return $this;
}
private function initRegistration()
{
$this->registration = $this->getKey('registration');
if ($this->registration) {
if ($this->registration->getSeason()) {
$season = $this->em->find(Season::class, $this->registration->getSeason()->getId());
$this->registration->setSeason($season);
}
}
// if (null !== ($id = $this->registration?->getId())) {
// $this->registration = $this->em->find(Registration::class, $id);
// }
}
public function getRegistration(): ?Registration
{
return $this->registration;
}
public function setRegistration(?Registration $registration): Session
{
$this->registration = $registration;
if (null === $registration) {
$this->removeKey('registration');
} else {
$this->setKey('registration', $registration);
}
return $this;
}
private function initUser()
{
$this->user = $this->getKey('user');
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): Session
{
$this->user = $user;
if (null === $user) {
$this->removeKey('user');
} else {
$this->setKey('user', $user);
}
return $this;
}
private function initCommunity()
{
$this->community = $this->getKey('community');
if (null === $this->community) {
$this->community = [
'isSponsor' => null,
'volunteer' => null,
'donation' => null,
];
}
if (null === $this->community['volunteer'] && $this->person?->getMeta()?->getVolunteer()) {
$this->community['volunteer'] = $this->person->getMeta()->getVolunteer();
}
if (null === $this->community['isSponsor'] && $this->person?->getMeta()?->getIsSponsor()) {
$this->community['isSponsor'] = $this->person->getMeta()->getIsSponsor();
}
}
public function getCommunity(): array
{
return $this->community;
}
public function setCommunity(array $community): Session
{
$this->community = $community;
$this->setKey('community', $community);
return $this;
}
private function initTutors()
{
$tutors = $this->getKey('tutors') ?? [];
foreach ($tutors as $tutor) {
if ($tutor->getId()) {
$tutor = $this->em->find(Person::class, $tutor->getId());
}
$this->tutors[] = $tutor;
}
}
/**
* @return Person[]
*/
public function getTutors(): array
{
return $this->tutors;
}
/**
* @param Person[] $tutor
* @return Session
*/
public function addTutor(Person $tutor): Session
{
$this->tutors[] = $tutor;
$this->setTutors($this->tutors);
return $this;
}
public function getTutor($key): ?Person
{
if (isset($this->tutors[$key])) {
return $this->tutors[$key];
}
return null;
}
public function setTutor($key, Person $tutor): self
{
if (isset($this->tutors[$key])) {
$this->tutors[$key] = $tutor;
$this->setTutors($this->tutors);
}
return $this;
}
public function removeTutor($key): self
{
if ($this->tutors[$key]) {
unset($this->tutors[$key]);
$this->setTutors($this->tutors);
}
return $this;
}
/**
* @param Person[] $tutors
* @return Session
*/
public function setTutors(array $tutors): Session
{
$this->setKey('tutors', $tutors);
return $this;
}
public function save()
{
//TODO: supprimer les tuteurs si majeur
//TODO: les supprimer en AJAX au changement d'âge ?
$person = $this->person;
$family = $this->family;
$tutors = $this->tutors;
$registration = $this->registration;
$community = $this->community;
$family->addPerson($person);
$person->addRegistration($registration);
foreach ($tutors ?? [] as $tutor) {
if (null === $tutor->getId()) {
$family->addPerson($tutor);
if (($tutor->getUser() === null)
&& ($tutor->getFirstEmail()->getOwner() === $tutor)
&& (null === $this->em->getRepository(User::class)
->findOneBy(['email' => $tutor->getFirstEmail()->getEmail()]))) {
$tutorUser = new User();
$tutorUser->setPerson($tutor)
->setEmail($tutor->getFirstEmail()->getEmail())
->setPlainPassword(uniqid('', true));
}
}
$person->addTutor($tutor);
}
$person->getMeta()
->setVolunteer($community['volunteer'])
->setIsSponsor($community['isSponsor']);
if ($community['donation']) {
$this->orderManager->updateDonation($registration, $community['donation']);
}
$season = $this->em->find(Season::class, $registration->getSeason()->getId());
foreach ($person->getProfilingPersons() as $profilingPerson) {
if ($profilingPerson->getSeason()->getId() === $season->getId()) {
$profiling = $this->em->find(Profiling::class, $profilingPerson->getProfiling()->getId());
$profilingPerson->setSeason($season)
->setPerson($person)
->setProfiling($profiling);
}
}
foreach ($person->getSectionPersons() as $sectionPerson) {
if ($sectionPerson->getSection()->getId() === $season->getSection()->getId()) {
$section = $this->em->find(Section::class, $sectionPerson->getSection()->getId());
$sectionPerson->setSection($section)
->setPerson($person);;
foreach ($sectionPerson->getSectionPersonMetas() as $sectionPersonMeta) {
$sectionMeta = $this->em->find(SectionMeta::class, $sectionPersonMeta->getSectionMeta()->getId());
$sectionPersonMeta->setSectionMeta($sectionMeta);
}
}
}
}
public function getStep(): int
{
return $this->step;
}
public function setStep(int $step): Session
{
$this->step = $step;
$this->setKey('step', $step);
return $this;
}
}