<?php
namespace App\Controller;
use App\Entity\ChampScientifique;
use App\Entity\TypePoste;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\Persistence\ManagerRegistry;
use App\Service\sendNotification;
use App\Service\logCandidatureService;
use Symfony\Component\Finder\Exception\AccessDeniedException as ExceptionAccessDeniedException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
use App\Entity\User;
use App\Entity\Candidature;
use App\Entity\PropositionRecrutement;
use App\Entity\Demandeur;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface;
use App\Form\RegistrationFormType;
use App\Form\Type\CandidatureType;
use App\Form\Type\EditCandidatureType;
use App\Security\AppCustomAuthenticator;
use App\Form\Type\CandidatureAcceptType;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\String\Slugger\SluggerInterface;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Knp\Component\Pager\PaginatorInterface;
class OffresController extends AbstractController
{
/**
* @Route("/offres/{lang}", name="app_offres_index", defaults={"lang": "fr"})
*/
public function index(Request $request, ManagerRegistry $doctrine, PaginatorInterface $paginator, $lang): Response
{
$entityManager = $doctrine->getManager();
// Filtre
$filtre = $request->get("filtre");
$tri = $request->get("tri");
$sens = $request->get("sens");
$pagination = $paginator->paginate ($entityManager->getRepository(Demandeur::class)->findForPublic($filtre, $tri, $sens), $request->get('page',1));
//$offres = $entityManager->getRepository(Demandeur::class)->findForPublic($filtre, $tri, $sens);
$types_poste = $entityManager->getRepository(TypePoste::class)->findAll();
$champs_scientifiques = $entityManager->getRepository(ChampScientifique::class)->findAll();
foreach($champs_scientifiques as $key => $champs_scientifique) {
$champs_scientifique->setTranslatableLocale($lang);
$entityManager->refresh($champs_scientifique);
$champs_scientifiques[$key] = $champs_scientifique;
}
return $this->renderForm('offres/index.html.twig', [
//'offres' => $offres,
'pagination' => $pagination,
'types_poste' => $types_poste,
'champs_scientifiques' => $champs_scientifiques,
'filtre' => $filtre,
'tri' => $tri,
'sens' => $sens,
'lang' => $lang
]);
}
/**
* @Route("/iframe/offres/{lang}", name="app_offres_iframe", defaults={"lang": "fr"})
*/
public function iframe(Request $request, ManagerRegistry $doctrine, PaginatorInterface $paginator, $lang): Response
{
$entityManager = $doctrine->getManager();
// Filtre
$filtre = $request->get("filtre");
$tri = $request->get("tri");
$sens = $request->get("sens");
$pagination = $paginator->paginate ($entityManager->getRepository(Demandeur::class)->findForPublic($filtre, $tri, $sens), $request->get('page',1));
//$offres = $entityManager->getRepository(Demandeur::class)->findForPublic($filtre, $tri, $sens);
$types_poste = $entityManager->getRepository(TypePoste::class)->findAll();
$champs_scientifiques = $entityManager->getRepository(ChampScientifique::class)->findAll();
foreach($champs_scientifiques as $key => $champs_scientifique) {
$champs_scientifique->setTranslatableLocale($lang);
$entityManager->refresh($champs_scientifique);
$champs_scientifiques[$key] = $champs_scientifique;
}
return $this->renderForm('offres/iframe.html.twig', [
//'offres' => $offres,
'pagination' => $pagination,
'types_poste' => $types_poste,
'champs_scientifiques' => $champs_scientifiques,
'filtre' => $filtre,
'tri' => $tri,
'sens' => $sens,
'lang' => $lang
]);
}
/**
* @Route("/offres/voir/{id}/{lang}", name="app_offres_voir")
*/
public function voir( Request $request,
ManagerRegistry $doctrine,
$id,
$lang='fr',
UserAuthenticatorInterface $userAuthenticator,
UserPasswordHasherInterface $userPasswordHasher,
AppCustomAuthenticator $appAuthenticator,
AuthenticationUtils $authenticationUtils,
sendNotification $sendNotification,
SluggerInterface $slugger,
logCandidatureService $logCandidatureService
): Response
{
$entityManager = $doctrine->getManager();
$session = $request->getSession();
$demandeur = $entityManager->getRepository(Demandeur::class)->find($id);
if(!$demandeur) {
throw new InvalidArgumentException("Cette demande n'existe pas");
}
if($demandeur->getEtat()->getId() != 5) {
throw new InvalidArgumentException("Cette offre n'a pas été validée");
}
// place l'id de l'offre en session pour une redirection après login
$session->getFlashBag()->get('redirect_id_demandeur'); // vider le "flashbag"
$session->getFlashBag()->add('redirect_id_demandeur', $id);
// Creation de compte
$user = $this->getUser();
if(!$user) {
$user = new User();
}
$formRegister = $this->createForm(RegistrationFormType::class, $user);
$formRegister->handleRequest($request);
if ($formRegister->isSubmitted() && $formRegister->isValid()) {
// username = email
$user->setUsername($formRegister->get('email')->getData());
// encode the plain password
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$formRegister->get('plainPassword')->getData()
)
);
// Role
$user->setRoles(['ROLE_EN_ATTENTE']);
$user->setEmailValidationChecksum(md5("P13".time()));
$entityManager->persist($user);
$entityManager->flush();
$sendNotification->send("validation-email-creation-compte", NULL, $user);
//return $userAuthenticator->authenticateUser($user, $appAuthenticator, $request);
$session->getFlashBag()->add('message', "Votre inscription sera finalisée après validation de votre adresse email. Vous allez recevoir un message contenant un lien permettant de finaliser l'inscription.");
return $this->redirectToRoute('app_edito');
}
// FIN - Creation de compte
// Gestion du login
// get the login error if there is one
$error_login = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
// FIN - Gestion du login
// === Candidature
$candidature = new Candidature;
$candidature->setCreatedAt(new \DateTimeImmutable(date("Y-m-d H:i:s")));
$candidature->setDemandeur($demandeur);
$candidature->setUser($user);
$etat_candidature = $entityManager->getReference('App\Entity\EtatCandidature', 1); // brouillon
$candidature->setEtatCandidature($etat_candidature);
$formCandidature = $this->createForm(CandidatureType::class, $candidature);
$formCandidature->handleRequest($request);
if ($formCandidature->isSubmitted() && $formCandidature->isValid()) {
/** @var UploadedFile $fichierCv */
$fichierCv = $formCandidature->get('fichierCv')->getData();
if ($fichierCv) {
$originalFilename = pathinfo($fichierCv->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $slugger->slug($originalFilename); // this is needed to safely include the file name as part of the URL
$newFilename = $safeFilename.'-'.uniqid().'.'.$fichierCv->guessExtension();
try { // Move the file to the directory where brochures are stored
$fichierCv->move(
$this->getParameter('cv_directory'),
$newFilename
);
} catch (FileException $e) {
$session->getFlashBag()->add('error', "Le fichier CV n'a pas pu être enregistré");
}
$candidature->setFichierCv($newFilename);
}
/** @var UploadedFile $fichierLm */
$fichierLm = $formCandidature->get('fichierLm')->getData();
if ($fichierLm) {
$originalFilename = pathinfo($fichierLm->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $slugger->slug($originalFilename); // this is needed to safely include the file name as part of the URL
$newFilename = $safeFilename.'-'.uniqid().'.'.$fichierLm->guessExtension();
try { // Move the file to the directory where brochures are stored
$fichierLm->move(
$this->getParameter('lm_directory'),
$newFilename
);
} catch (FileException $e) {
$session->getFlashBag()->add('error', "Le fichier LM n'a pas pu être enregistré");
}
$candidature->setFichierLm($newFilename);
}
/** @var UploadedFile $fichierIdentite */
$fichierIdentite = $formCandidature->get('fichierIdentite')->getData();
if ($fichierIdentite) {
$originalFilename = pathinfo($fichierIdentite->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $slugger->slug($originalFilename); // this is needed to safely include the file name as part of the URL
$newFilename = $safeFilename.'-'.uniqid().'.'.$fichierIdentite->guessExtension();
try { // Move the file to the directory where brochures are stored
$fichierIdentite->move(
$this->getParameter('identite_directory'),
$newFilename
);
} catch (FileException $e) {
$session->getFlashBag()->add('error', "Le fichier pièce d'identité n'a pas pu être enregistré");
}
$candidature->setFichierIdentite($newFilename);
}
/** @var UploadedFile $fichierDiplome */
$fichierDiplome = $formCandidature->get('fichierDiplome')->getData();
if ($fichierDiplome) {
$originalFilename = pathinfo($fichierDiplome->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $slugger->slug($originalFilename); // this is needed to safely include the file name as part of the URL
$newFilename = $safeFilename.'-'.uniqid().'.'.$fichierDiplome->guessExtension();
try { // Move the file to the directory where brochures are stored
$fichierDiplome->move(
$this->getParameter('diplomes_directory'),
$newFilename
);
} catch (FileException $e) {
$session->getFlashBag()->add('error', "Le fichier Diplôme n'a pas pu être enregistré");
}
$candidature->setFichierDiplome($newFilename);
}
/** @var UploadedFile $fichierRecommandation */
/*
$fichierRecommandation = $formCandidature->get('fichierRecommandation')->getData();
if ($fichierRecommandation) {
$originalFilename = pathinfo($fichierRecommandation->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $slugger->slug($originalFilename); // this is needed to safely include the file name as part of the URL
$newFilename = $safeFilename.'-'.uniqid().'.'.$fichierRecommandation->guessExtension();
try { // Move the file to the directory where brochures are stored
$fichierRecommandation->move(
$this->getParameter('recommandation_directory'),
$newFilename
);
} catch (FileException $e) {
$session->getFlashBag()->add('error', "La lettre de recommendation n'a pas pu être enregistrée");
}
$candidature->setFichierRecommandation($newFilename);
}*/
$etat_candidature = $entityManager->getReference('App\Entity\EtatCandidature', 2); // En attente de validation par l'administrateur
$candidature->setEtatCandidature($etat_candidature);
// Civilité
if($formCandidature->get("civilite")->getData()) {
$user->setCivilite($formCandidature->get("civilite")->getData());
$entityManager->persist($user);
}
$entityManager->persist($candidature);
$entityManager->flush();
// logCandidature
$logCandidatureService->log("Création de la candidature par le candidat", $candidature, $user);
$session->getFlashBag()->add('message', "Votre candidature a été enregistrée. Elle va être examinée par un administrateur.");
}
// FIN Candidature
// test de candidatures existante
$candidatures_existantes = $entityManager->getRepository(Candidature::class)->findBy(['demandeur' => $demandeur, 'user' => $user]);
$demandeur->setTranslatableLocale($lang);
$entityManager->refresh($demandeur);
return $this->renderForm('offres/voir.html.twig', [
'demandeur' => $demandeur,
'registrationForm' => $formRegister,
'candidatureForm' => $formCandidature,
'error_login' => $error_login,
'last_username' => $lastUsername,
'lang' => $lang,
'candidatures_existantes' => $candidatures_existantes
]);
}
/**
* @Route("/user/mes-candidatures/edit/{id}", name="app_candidature_edit")
*/
public function editCandidature( Request $request,
ManagerRegistry $doctrine,
$id,
$lang='fr',
sendNotification $sendNotification,
SluggerInterface $slugger,
logCandidatureService $logCandidatureService
): Response
{
$entityManager = $doctrine->getManager();
$session = $request->getSession();
$user = $this->getUser();
$candidature = $entityManager->getRepository(Candidature::class)->find($id);
if(!$candidature) {
throw new InvalidArgumentException("Cette candidature n'existe pas");
}
if( !($candidature->getEtatCandidature()->getId() == 1 || $candidature->getEtatCandidature()->getId() == 3)) {
throw new InvalidArgumentException("Cette candidature n'est pas éditable");
}
if( $candidature->getUser()->getId() != $user->getId()) {
throw new InvalidArgumentException("Cette candidature n'est pas liée a votre compte");
}
$formCandidature = $this->createForm(EditCandidatureType::class, $candidature);
$formCandidature->handleRequest($request);
if ($formCandidature->isSubmitted() && $formCandidature->isValid()) {
/** @var UploadedFile $fichierCv */
$fichierCv = $formCandidature->get('fichierCv')->getData();
if ($fichierCv) {
$originalFilename = pathinfo($fichierCv->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $slugger->slug($originalFilename); // this is needed to safely include the file name as part of the URL
$newFilename = $safeFilename.'-'.uniqid().'.'.$fichierCv->guessExtension();
try { // Move the file to the directory where brochures are stored
$fichierCv->move(
$this->getParameter('cv_directory'),
$newFilename
);
} catch (FileException $e) {
$session->getFlashBag()->add('error', "Le fichier CV n'a pas pu être enregistré");
}
$candidature->setFichierCv($newFilename);
}
/** @var UploadedFile $fichierLm */
$fichierLm = $formCandidature->get('fichierLm')->getData();
if ($fichierLm) {
$originalFilename = pathinfo($fichierLm->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $slugger->slug($originalFilename); // this is needed to safely include the file name as part of the URL
$newFilename = $safeFilename.'-'.uniqid().'.'.$fichierLm->guessExtension();
try { // Move the file to the directory where brochures are stored
$fichierLm->move(
$this->getParameter('lm_directory'),
$newFilename
);
} catch (FileException $e) {
$session->getFlashBag()->add('error', "Le fichier LM n'a pas pu être enregistré");
}
$candidature->setFichierLm($newFilename);
}
/** @var UploadedFile $fichierIdentite */
$fichierIdentite = $formCandidature->get('fichierIdentite')->getData();
if ($fichierIdentite) {
$originalFilename = pathinfo($fichierIdentite->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $slugger->slug($originalFilename); // this is needed to safely include the file name as part of the URL
$newFilename = $safeFilename.'-'.uniqid().'.'.$fichierIdentite->guessExtension();
try { // Move the file to the directory where brochures are stored
$fichierIdentite->move(
$this->getParameter('identite_directory'),
$newFilename
);
} catch (FileException $e) {
$session->getFlashBag()->add('error', "Le fichier pièce d'identité n'a pas pu être enregistré");
}
$candidature->setFichierIdentite($newFilename);
}
/** @var UploadedFile $fichierDiplome */
$fichierDiplome = $formCandidature->get('fichierDiplome')->getData();
if ($fichierDiplome) {
$originalFilename = pathinfo($fichierDiplome->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $slugger->slug($originalFilename); // this is needed to safely include the file name as part of the URL
$newFilename = $safeFilename.'-'.uniqid().'.'.$fichierDiplome->guessExtension();
try { // Move the file to the directory where brochures are stored
$fichierDiplome->move(
$this->getParameter('diplomes_directory'),
$newFilename
);
} catch (FileException $e) {
$session->getFlashBag()->add('error', "Le fichier Diplôme n'a pas pu être enregistré");
}
$candidature->setFichierDiplome($newFilename);
}
/** @var UploadedFile $fichierRecommandation */
/*
$fichierRecommandation = $formCandidature->get('fichierRecommandation')->getData();
if ($fichierRecommandation) {
$originalFilename = pathinfo($fichierRecommandation->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $slugger->slug($originalFilename); // this is needed to safely include the file name as part of the URL
$newFilename = $safeFilename.'-'.uniqid().'.'.$fichierRecommandation->guessExtension();
try { // Move the file to the directory where brochures are stored
$fichierRecommandation->move(
$this->getParameter('recommandation_directory'),
$newFilename
);
} catch (FileException $e) {
$session->getFlashBag()->add('error', "La lettre de recommendation n'a pas pu être enregistrée");
}
$candidature->setFichierRecommandation($newFilename);
}*/
$etat_candidature = $entityManager->getReference('App\Entity\EtatCandidature', 2); // En attente de validation par l'administrateur
$candidature->setEtatCandidature($etat_candidature);
$entityManager->persist($candidature);
$entityManager->flush();
// logCandidature
$logCandidatureService->log("Modification de la candidature par le candidat", $candidature, $user);
$session->getFlashBag()->add('message', "Votre candidature a été enregistrée. Elle va être examinée par un administrateur.");
return $this->redirectToRoute('mes_candidatures');
}
// FIN Candidature
return $this->renderForm('offres/editCandidature.html.twig', [
'candidature' => $candidature,
'candidatureForm' => $formCandidature,
'lang' => $lang
]);
}
/**
* @Route("/candidature/voir-pj/{type}/{id_candidature}", name="candidature_voir_pj")
*/
public function voirPJ($type, $id_candidature,
Request $request,
ManagerRegistry $doctrine
)
{
$entityManager = $doctrine->getManager();
$session = $request->getSession();
$filePath="";
/** @var Candidature $candidature */
$candidature = $entityManager->getRepository(Candidature::class)->find($id_candidature);
if(!$candidature)
{
throw new InvalidArgumentException("Cette candidature n'existe pas");
}
// TODO: vérification des droits
if($type == 'cv')
{
$filePath = $this->getParameter('cv_directory')."/".$candidature->getFichierCv();
if(file_exists($filePath)) {
$file = new File($filePath);
return $this->file($file, null, ResponseHeaderBag::DISPOSITION_INLINE);
}
}
if($type == 'lm')
{
$filePath = $this->getParameter('lm_directory')."/".$candidature->getFichierLm();
if(file_exists($filePath)) {
$file = new File($filePath);
return $this->file($file, null, ResponseHeaderBag::DISPOSITION_INLINE);
}
}
if($type == 'diplome')
{
$filePath = $this->getParameter('diplomes_directory')."/".$candidature->getFichierDiplome();
if(file_exists($filePath)) {
$file = new File($filePath);
return $this->file($file, null, ResponseHeaderBag::DISPOSITION_INLINE);
}
}
if($type == 'recommendation')
{
$filePath = $this->getParameter('recommandation_directory')."/".$candidature->getFichierRecommandation();
if(file_exists($filePath)) {
$file = new File($filePath);
return $this->file($file, null, ResponseHeaderBag::DISPOSITION_INLINE);
}
}
if($type == 'identite')
{
$filePath = $this->getParameter('identite_directory')."/".$candidature->getFichierIdentite();
if(file_exists($filePath)) {
$file = new File($filePath);
return $this->file($file, null, ResponseHeaderBag::DISPOSITION_INLINE);
}
}
throw new InvalidArgumentException("Fichier introuvable : ".$filePath);
}
/**
* @Route("/user/mes-candidatures", name="mes_candidatures")
*/
public function mesCandidatures(
Request $request,
ManagerRegistry $doctrine
)
{
$entityManager = $doctrine->getManager();
$candidatures = $entityManager->getRepository(Candidature::class)->findBy(['user' => $this->getUser()]);
return $this->renderForm('offres/mesCandidatures.html.twig', [
'candidatures' => $candidatures,
]);
}
/**
* @Route("/user/mes-candidatures/accepte/{id}", name="app_candidature_accepte")
*/
public function accepteCandidature( Request $request,
ManagerRegistry $doctrine,
$id,
$lang='fr',
sendNotification $sendNotification,
logCandidatureService $logCandidatureService
): Response
{
$entityManager = $doctrine->getManager();
$session = $request->getSession();
$user_connected = $this->getUser();
$candidature = $entityManager->getRepository(Candidature::class)->find($id);
if(!$candidature) {
throw new InvalidArgumentException("Cette candidature n'existe pas");
}
if($candidature->getEtatCandidature()->getId() != 6) {
throw new InvalidArgumentException("Cette candidature n'est pas retenue");
}
if( $candidature->getUser()->getId() != $user_connected->getId()) {
throw new InvalidArgumentException("Cette candidature n'est pas liée a votre compte");
}
$formCandidature = $this->createForm(CandidatureAcceptType::class, $candidature);
$formCandidature->handleRequest($request);
if ($formCandidature->isSubmitted() && $formCandidature->isValid()) {
$etat_candidature = $entityManager->getReference('App\Entity\EtatCandidature', 7); // Invitation acceptée
$candidature->setEtatCandidature($etat_candidature);
$entityManager->persist($candidature);
$entityManager->flush();
// logCandidature
$logCandidatureService->log("Invitation acceptée par le candidat", $candidature, $user_connected);
$session->getFlashBag()->add('message', "Votre candidature est acceptée, vous allez être contacté par le gestionnaire et recevoir une proposition de recrutement.");
// notifiaction email aux admin
$sendNotification->send("notification-acceptation-candidat", $candidature->getDemandeur(), $candidature->getUser(), $candidature);
// Notification de refus email aux autres candidats
$candidatures = $entityManager->getRepository(Candidature::class)->findByDemandeurOrderByRang($candidature->getDemandeur());
$etat_candidature_refus = $entityManager->getReference('App\Entity\EtatCandidature', 9); // refusée
foreach($candidatures as $candidature_refus) {
if($candidature_refus->getId() != $candidature->getId()) {
$candidature_refus->setEtatCandidature($etat_candidature_refus);
$entityManager->persist($candidature_refus);
$entityManager->flush();
// logCandidature
$logCandidatureService->log("Candidature refusée après acceptation du candidat de rang ".$candidature->getRang()." Email de refus envoyé", $candidature_refus, $user_connected);
$sendNotification->send("refus-apres-confirmation-du-candidat-1", $candidature->getDemandeur(), $candidature_refus->getUser(), $candidature_refus);
}
}
return $this->redirectToRoute('mes_candidatures');
}
// FIN Candidature
return $this->renderForm('offres/accepteCandidature.html.twig', [
'candidature' => $candidature,
'candidatureForm' => $formCandidature,
'lang' => $lang
]);
}
/**
* @Route("/candidature/voir-proposition/{id_proposition}", name="candidature_voir_proposition")
*/
public function voirProposition($id_proposition,
Request $request,
ManagerRegistry $doctrine,
logCandidatureService $logCandidatureService
)
{
$entityManager = $doctrine->getManager();
$session = $request->getSession();
$user_connected = $this->getUser();
$filePath="";
/** @var Candidature $candidature */
$propositionRecrutement = $entityManager->getRepository(PropositionRecrutement::class)->find($id_proposition);
if(!$propositionRecrutement)
{
throw new InvalidArgumentException("Cette proposition n'existe pas");
}
if( $propositionRecrutement->getCandidature()->getUser()->getId() != $user_connected->getId()) {
throw new InvalidArgumentException("Cette proposition n'est pas liée a votre compte");
}
if($request->get("signer")) {
$etat_proposition = $entityManager->getReference('App\Entity\EtatPropositionRecrutement', 3); // signée
$propositionRecrutement->setEtat($etat_proposition);
$entityManager->persist($propositionRecrutement);
$entityManager->flush();
// logCandidature
$logCandidatureService->log("Signature par le candidat de la proposition de recrutement", $propositionRecrutement->getCandidature(), $user_connected);
$session->getFlashBag()->add('message', "Votre signature a bien été enregistrée.");
}
return $this->renderForm('offres/voirPropositionRecrutement.html.twig', [
'propositionRecrutement' => $propositionRecrutement,
]);
}
}