<?php
namespace App\Controller\EspaceParent;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use App\Manager\PaiementManager;
use App\Entity\Commande;
use App\Entity\Compta;
use App\Entity\ContactForFamilleAccueil;
use App\Entity\TiersDeConfiance;
use App\Entity\ContactPropertyValue;
use App\Entity\FrontOption;
use App\Entity\MessageParent;
use App\Entity\Inscription;
use App\Entity\Media;
use App\Entity\Metier;
use App\Entity\Property;
use App\Entity\SejourSession;
use App\Entity\SejourSessionEquipier;
use App\Factory\ParentFactory;
use App\Form\ContactForFamilleAccueilType;
use App\Form\ContactPropertyValueType;
use App\Form\MessageParentType;
use App\Form\MissingPropertyType;
use App\Form\ParentContactType;
use App\Form\TiersDeConfianceType;
use App\Frontend\Controller\TiersDeConfianceController;
use App\Manager\DocumentManager;
use App\Manager\PropertyManager;
use App\Message\SendEmailMessage;
use Doctrine\ORM\EntityManagerInterface;
use App\Repository\ContactRepository;
use App\Repository\InscriptionRepository;
use App\Repository\SejourSessionRepository;
use App\Utility\InscriptionUpdater;
use App\Utility\PropertyAndMediaUpdater;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use App\Form\PropertyCollectionType;
class EspaceParentController extends AbstractController
{
/**
* @Route("/espace-parent", name="espace_parent")
* @Route("/espace-parent/tab_{tab}", name="espace_parent_tab")
*/
public function index(
PaiementManager $pm,
EntityManagerInterface $em,
DocumentManager $dm,
PropertyManager $prm,
Request $request,
$tab = null
): Response {
$error = [];
$parent = $this->getUser()->getContact();
$enfants = $parent->getChildren();
$profilIncomplet = false;
foreach ($parent->getContactPropertyValues() as $prop) {
if ($prop->getProperty()->getIsMandatory() && $prop->getValue() == null && $profilIncomplet == false) {
$profilIncomplet = true;
$error[] = ['votre profil est incomplet: ' . $prop->getProperty()->getName(), 'action' => ['name' => 'completer vos informations', 'lien' => 'toutou']];
}
}
if ($parent->getLocation() == null) {
$error[] = ['votre profil est incomplet', 'action' => ['name' => 'completer vos informations', 'lien' => 'toutou']];
}
foreach ($enfants as $enfant) {
$profilIncomplet = false;
foreach ($enfant->getContactPropertyValues() as $prop) {
$profilIncomplet = false;
if ($prop->getProperty()->getIsMandatory() && $prop->getValue() == null && $profilIncomplet == false) {
$profilIncomplet = true;
$error[] = ['le profil de ' . $enfant->getFirstName() . ' est incomplet', 'action' => ['name' => 'completer vos informations', 'lien' => 'toutou']];
}
}
}
$documentsManquants = [];
$hasMissing = false;
$resas = $this->getUser()->getContact()->getInscriptionParents();
$commandes = $em->getRepository(Commande::class)->retrieveCommandesFromContact($this->getUser()->getContact());
$now = new \Datetime();
$isOpen = [];
$paiementOverview = [];
$paiementDone = [];
// foreach ($resas as $resa) {
// if ($resa->getSejourSession()->getDateDebut() > $now && ($resa->getStatut() !== Inscription::CANCELLED || $resa->getStatut() !== null)) {
// $resa = $dm->hasInscriptionAllMandatoryDocumentation($resa);
// $resa = $prm->hasInscriptionAllMandatoryProperty($resa);
// $em->refresh($resa);
// }
// }
foreach ($commandes as $commande) {
$em->refresh($commande);
if ($commande->getStatut() !== Compta::STATUT_COMPLETE && $commande->getStatut() !== Commande::STATUT_CANCELLED && $commande->getStatut() !== Commande::STATUT_TO_BE_DELETED) {
$paiementOverview[$commande->getId()]['commande'] = $commande;
$paiementOverview[$commande->getId()]['paiement'] = [];
foreach ($commande->getCompta() as $compta) {
$paiementOverview[$commande->getId()]['paiement'] = [
$commande->getPaiementOverview()
];
}
}
if ($commande->getStatut() == Compta::STATUT_COMPLETE) {
$paiementDone[$commande->getId()]['commande'] = $commande;
$paiementDone[$commande->getId()]['paiement'] = [];
foreach ($commande->getCompta() as $compta) {
$paiementDone[$commande->getId()]['paiement'] = [
$commande->getPaiementOverview()
];
}
}
}
$infosManquantes = [];
foreach ($resas as $resa) {
$em->refresh($resa);
if ($resa->getSejourSession()->getDateDebut() > $now && ($resa->getStatut() !== null && $resa->getStatut() !== Inscription::CANCELLED)) {
$resa = $dm->hasInscriptionAllMandatoryDocumentation($resa);
$resa = $prm->hasInscriptionAllMandatoryProperty($resa);
$dm->removeDoubleMedia($resa);
$documentsManquants[] = ['documents' => $dm->listMissingDocFromInscription($resa, false), 'resa' => $resa, 'incomplete' => false];
if (count($prm->listMissingPropertyFromInscription($resa)) > 0) {
$infosManquantes = array_merge($infosManquantes, $prm->listMissingPropertyFromInscription($resa));
foreach ($documentsManquants as $key => $missingDoc) {
if ($missingDoc['resa'] == $resa) {
$documentsManquants[$key]['incomplete'] = true;
$hasMissing = true;
}
}
}
}
}
$enquete = $em->getRepository(FrontOption::class)->findOneBy(['name' => 'lienEnquete']);
return $this->render('espace_parent/index.html.twig', [
'hasMissing' => $hasMissing,
'paiementOverview' => $paiementOverview,
'documentManquants' => $documentsManquants,
'infosManquantes' => $infosManquantes,
'lienEnquete' => $enquete,
'paiementDone' => $paiementDone,
'tab' => $tab ?? $request->get('tab')
]);
}
/**
* @Route("/espace-parent/validationContactFamilleAccueil/{id}", name="espace_parent_validation_contact_famille_accueil")
*/
public function contactFamilleAccueil(ContactForFamilleAccueil $cffa, EntityManagerInterface $em, Request $request)
{
$form = $this->createForm(ContactForFamilleAccueilType::class, $cffa);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($cffa);
$em->flush();
return $this->redirectToRoute('espace_parent');
}
return $this->render(
'espace_parent/contactAccueil.html.twig',
[
'form' => $form->createView(),
'cffa' => $cffa
]
);
}
/**
* @Route("/espace-parent/uploadDoc/{id}", name="espace_parent_upload_doc")
* @Route("/espace-candidature/uploadDoc/{id}", name="espace_candidature_upload_doc")
*/
public function uploadDoc(Request $request, int $id, EntityManagerInterface $em, ValidatorInterface $vi)
{
$media = $em->getRepository(Media::class)->findOneById($id);
$params = $this->getRefererParams($request);
$this->denyAccessUnlessGranted('POST_VIEW', $media);
if ($media->getInscription() !== null && $media->getInscription()->getStatut() == Inscription::CANCELLED) {
$this->addFlash('danger', 'Le fichier ne correspond pas au format demandé (' . implode(",", $media->getMediaCategorie()->getAllowedFormat()) . ")");
return new jsonResponse('Format non valide');
}
$parent = $media;
foreach ($request->files as $file) {
if (!$media->setPrivateFile($file)) {
$this->addFlash('danger', 'Le fichier ne correspond pas au format demandé (' . implode(",", $media->getMediaCategorie()->getAllowedFormat()) . ")");
return new jsonResponse('Format non valide');
}
if ($media->getMediaCategorie()->getName() == 'Photo') {
$contact = $media->getContact();
$this->convertAndSaveToBMP($file, $contact);
}
$media->setIsValidated(false);
$em->persist($media);
$media->setUpdatedDate(new \Datetime());
$media = (new Media())->setMediaParent($parent)->setMediaCategorie($parent->getMediaCategorie());
if ($media->getMediaCategorie()->getIsPrivate()) {
$media->setPrivateFile($media->getImgFile());
$media->setImgFile(null);
}
}
$em->flush();
return new jsonResponse('OK');
if (array_key_exists('id', $params)) {
return $this->redirect($this->generateUrl($params['_route'], ['id' => $params['id']]));
}
return $this->redirect($this->generateUrl($params['_route'], ['tab' => "dossier"]));
}
private function convertAndSaveToBMP($file, $contact)
{
$tempFilePath = $file->getPathname();
$uploadDirectory = $this->getParameter('kernel.project_dir') . '/public/bmp/';
if (!is_dir($uploadDirectory)) {
mkdir($uploadDirectory, 0777, true);
}
// Retrieve ID, prenom, and nom from media's contact
$id = $contact->getId();
$prenom = $contact ? $contact->getFirstName() : 'unknown';
$nom = $contact ? $contact->getLastName() : 'unknown';
// Sanitize prenom and nom to avoid illegal filename characters
$prenom = preg_replace('/[^a-zA-Z0-9_-]/', '', $prenom);
$nom = preg_replace('/[^a-zA-Z0-9_-]/', '', $nom);
$newFileName = sprintf('%d-%s-%s.bmp', $id, $prenom, $nom);
$newFilePath = $uploadDirectory . $newFileName;
$image = imagecreatefromstring(file_get_contents($tempFilePath));
if ($image !== false) {
if (function_exists('imagebmp')) {
imagebmp($image, $newFilePath);
} else {
// If BMP is not supported, fall back to PNG format
$newFilePath = str_replace('.bmp', '.png', $newFilePath);
imagepng($image, $newFilePath);
}
imagedestroy($image);
} else {
$this->addFlash('danger', 'Erreur lors de la conversion de l\'image en BMP ou PNG.');
}
}
/**
* @Route("/espace-parent/deleteDoc/{id}", name="espace_parent_delete_doc", methods={"DELETE"})
* @Route("/espace-candidature/deleteDoc/{id}", name="espace_candidature_delete_doc", methods={"DELETE"})
*/
public function removeFile(int $id, EntityManagerInterface $em): JsonResponse
{
$media = $em->getRepository(Media::class)->findOneById($id);
if (!$media) {
return new JsonResponse(['error' => 'Fichier non trouvé.'], 404);
}
$this->denyAccessUnlessGranted('POST_VIEW', $media);
try {
unlink($media->getFilePath());
$media->setFilePath(null);
$em->persist($media);
$em->flush();
return new JsonResponse(['message' => 'Fichier supprimé avec succès.'], 200);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Une erreur est survenue lors de la suppression du fichier.'], 500);
}
}
/**
* @Route("/espace-parent/infoManquantes",name="espace_parent_missing_properties")
*/
public function missingProperties(PropertyManager $prm, Request $request)
{
$infosManquantes = [];
$resas = $this->getUser()->getContact()->getInscriptionParents();
foreach ($resas as $resa) {
$infosManquantes = array_merge($infosManquantes, $prm->listMissingPropertyFromInscription($resa));
}
$form = $this->createForm(MissingPropertyType::class, null, ['missingProperties' => $infosManquantes]);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$response = $form->getData();
//TODO: voters
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('espace_parent');
}
return $this->render('espace_parent/informationsManquantes.html.twig', ['missingProperties' => $infosManquantes, 'form' => $form->createView()]);
}
//regarder si pas le passer en trait.
private function getRefererParams(Request $request)
{
$referer = $request->headers->get('referer');
$baseUrl = $request->getSchemeAndHttpHost();
$lastPath = substr($referer, strpos($referer, $baseUrl) + strlen($baseUrl));
return $this->get('router')->getMatcher()->match(substr($lastPath, 0, strpos($lastPath, '?')));
}
/**
* @Route("/espace-parent/photosSejour/{id}", name="espace_parent_photos_sejour")
*/
public function photoSejours(EntityManagerInterface $em, SejourSession $sejourSession)
{
$this->denyAccessUnlessGranted('POST_VIEW', $sejourSession);
return $this->render('espace_parent/photosSejour.html.twig', ['sejourSession' => $sejourSession]);
}
/**
* @Route("/espace-parent/messagesDirecteur/{id}", name="espace_parent_message_directeur")
*/
public function messagesDirecteurs(EntityManagerInterface $em, SejourSession $sejourSession)
{
$this->denyAccessUnlessGranted('POST_VIEW', $sejourSession);
return $this->render('espace_parent/messageDirecteur.html.twig', ['sejourSession' => $sejourSession]);
}
/**
* @Route("/espace-parent/info/modifier/{id}",name="espace_parent_modify_property")
*/
public function modifyProperty(EntityManagerInterface $em, $id, Request $request, InscriptionUpdater $inscriptionUpdater)
{
$property = $em->getRepository(ContactPropertyValue::class)->findOneById($id);
$enfant = $property->getContact();
$this->denyAccessUnlessGranted('view', $enfant);
$form = $this->createForm(ContactPropertyValueType::class, $property);
//$form->add('Sauver', SubmitType::class, ['attr' => ['class' => 'button bounce item-sejour__button'],'label'=>'Enregistrer et Sauver']);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em->persist($property);
$em->flush();
$inscriptionUpdater->updateInscription($property);
return new JsonResponse(['id' => $id]);
}
if ($form->isSubmitted() and !$form->isValid()) {
$vcString = $property->getProperty()->getValidationClass();
if ($vcString !== null) {
$vc = new $vcString();
return new JsonResponse(['error' => $vc->getErrorMessage()]);
}
}
return $this->render('frontend/simpleForm.html.twig', ['form' => $form->createView(), 'pageTitle' => 'Mise à jour information']);
}
/**
* @Route("/espace-parent/equipe-peda/{id}",name="espace_parent_equipe_peda")
*/
public function equipePeda(SejourSessionRepository $ssrp, int $id)
{
$sejourSession = $ssrp->findOneById($id);
$equipiers = $sejourSession->getSejourSessionEquipiers();
return $this->render('espace_parent/equipe_peda.html.twig', [
'sejourSession' => $sejourSession,
'equipiers' => $equipiers
]);
}
/**
* @Route("/espace-parent/messageEnfant/{id}", name="espace_parent_message")
*/
public function MessageEnfant(EntityManagerInterface $em, $id, Request $request, MessageBusInterface $bus)
{
$inscription = $em->getRepository(Inscription::class)->findOneBy([
'id' => $id,
'parent' => $this->getUser()->getContact()
]);
$messageParent = new MessageParent();
$messageParent->setSejourSession($inscription->getSejourSession());
$messageParent->setEnfant($inscription->getEnfant()->getFirstName() . " " . $inscription->getEnfant()->getLastName());
$messageParent->setEmail($this->getUser()->getEmail());
$messageParent->setParent($this->getUser()->getContact()->getFirstName() . " " . $this->getUser()->getContact()->getLastName());
$messageParent->setIsValid(true);
$form = $this->createForm(MessageParentType::class, $messageParent);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em->persist($messageParent);
$em->flush();
$directeur = $em->getRepository(Metier::class)->findOneByName("Directeur");
$contact = $em->getRepository(SejourSessionEquipier::class)->findOneBy(
[
'metier' => $directeur,
'sejourSession' => $inscription->getSejourSession()
]
);
$this->addFlash('success', 'votre message est bien envoyé');
$bus->dispatch((new SendEmailMessage('email_parents', '', $messageParent->getId(), $contact->getContact()->getEmail())));
//TODO: message au directeurs.
return $this->redirectToRoute("espace_parent");
}
return $this->render('frontend/form.html.twig', ['form' => $form->createView(), 'pageTitle' => 'Message à mon enfant']);
}
/**
* @Route("/espace-parent/vueProfilEnfant/{id}", name="espace_parent_enfant")
* @Route("/espace-candidat/vueProfil", name="espace_candidature_modify")
*/
public function ProfilEnfant(ContactRepository $cp, EntityManagerInterface $em, Request $request, $id = null)
{
$mandatoryPropertiesEnfant = $em->getRepository(Property::class)->findBy([
'type' => 'enfant',
'isFactory' => true
]);
//TODO: voters pour voir si a droit de voir l'enfant
if ($id !== null) {
$isEnfant = true;
$enfant = $cp->findOneById($id);
$this->denyAccessUnlessGranted('view', $enfant);
$params = $this->getRefererParams($request);
foreach ($mandatoryPropertiesEnfant as $property) {
$cpv = $em->getRepository(ContactPropertyValue::class)->findBy([
'property' => $property,
'contact' => $enfant
]);
if ($cpv == null) {
$newCpv = new ContactPropertyValue();
$newCpv->setContact($enfant);
$newCpv->setProperty($property);
$newCpv->setValue($property->getDefault());
$em->persist($newCpv);
$enfant->addContactPropertyValue($newCpv);
}
}
$filesEnfant = $em->getRepository(Media::class)->findBy(['contact' => $enfant]);
} else {
$isEnfant = false;
$enfant = $this->getUser()->getContact();
$filesEnfant = $em->getRepository(Media::class)->findCandidaturesFiles($enfant);
}
$form = $this->createForm(PropertyCollectionType::class, $enfant, array('csrf_protection' => false));
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em->flush();
$this->addFlash('success', 'Informations modifiées');
if ($id !== null)
return $this->redirectToRoute("espace_parent", ['tab' => 'dossier']);
}
$em->flush();
return $this->render(
'espace_parent/profil_enfant.html.twig',
[
'enfant' => $enfant,
'documents' => $filesEnfant,
'referer' => $request->headers->get('referer'),
'isEnfant' => $isEnfant,
'form' => $form->createView(),
]
);
}
/**
* @Route("/espace-parent/ajoutTiersDeConfiance/{id}", name="ajout-tiers-de-confiance")
*/
public function addTiersDeConfiance(EntityManagerInterface $em, ParentFactory $pf, Request $request, $id)
{
$inscription = $em->getRepository(Inscription::class)->findOneById($id);
$this->denyAccessUnlessGranted('POST_VIEW', $inscription);
$tdc = new TiersDeConfiance();
$tdc->setInscription($inscription);
$tdc->setMain($this->getUser()->getContact());
$contact = $pf->createContact();
$tdc->setTiers($contact);
foreach ($contact->getContactPropertyValues() as $cpv) {
$em->persist($cpv->getProperty());
$em->persist($cpv);
}
$em->persist($tdc->getTiers());
$em->flush();
$form = $this->createForm(TiersDeConfianceType::class, $tdc);
$form->get('tiers')->remove('certif');
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em->persist($tdc);
$em->flush();
$this->addFlash('success', 'ajout d\'un tiers de confiance effectué');
return $this->redirectToRoute('espace_parent');
}
return $this->render('espace_parent/tiersDeConfiance.html.twig', ['form' => $form->createView()]);
}
/**
* @Route("espace-parent/mes-informations", name="espace-parent_mes-informations")
*/
public function mesInformations(Request $request, EntityManagerInterface $em)
{
$form = $this->createForm(ParentContactType::class, $this->getUser()->getContact());
$form->remove('certif');
$form->add('valider', SubmitType::class, ['attr' => ['class' => 'btn btn-primary bounce small-spacing-before']]);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em->flush();
$this->addFlash('success', 'Informations modifiées');
return $this->redirectToRoute('espace_parent');
}
return $this->render('frontend/form.html.twig', ['form' => $form->createView(), 'pageTitle' => 'mes Coordonnées']);
}
/**
* @Route("/espace-parent/modifier-profil-enfant/{id}", name="espace-parent_enfant_edit")
*/
public function modifyProfilEnfant(PropertyManager $prm, Request $request, int $id, ContactRepository $cp, EntityManagerInterface $em)
{
$enfant = $cp->findOneById($id);
$this->denyAccessUnlessGranted('view', $enfant);
$allProperties = $em->getRepository(ContactPropertyValue::class)->findBy([
'contact' => $enfant
]);
$form = $this->createForm(MissingPropertyType::class, null, ['missingProperties' => [$allProperties]]);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$response = $form->getData();
//TODO: voters
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('espace_parent');
}
return $this->render('espace_parent/informationsManquantes.html.twig', ['missingProperties' => $allProperties, 'form' => $form->createView()]);
}
/**
* @Route("espace-parent/responsable/{id}", name="contact_edit")
*/
public function responsableEdit(Request $request, EntityManagerInterface $em, int $id, ContactRepository $cp)
{
$responsable = $cp->findOneById($id);
$form = $this->createForm(ParentContactType::class, $responsable);
$form->remove('certif');
$form->add('valider', SubmitType::class, ['attr' => ['class' => 'btn btn-primary bounce small-spacing-before']]);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em->flush();
$this->addFlash('success', 'Informations modifiées');
return $this->redirectToRoute('espace_parent');
}
return $this->render('frontend/form.html.twig', ['form' => $form->createView(), 'pageTitle' => 'mes Coordonnées']);
}
/**
* @Route("/espace-parent/oldSejours",name="espace-parent_old-sejours")
*/
public function oldSejours(InscriptionRepository $inscriptionRepo, EntityManagerInterface $em): Response
{
$inscriptions = $inscriptionRepo->findOld($this->getUser());
$enquete = $em->getRepository(FrontOption::class)->findOneBy(['name' => 'lienEnquete']);
return $this->render('espace_parent/old_sejours.html.twig', [
'inscriptions' => $inscriptions,
'lienEnquete' => $enquete
]);
}
}