<?php
declare(strict_types=1);
/*
* Copyright (C) Office National de Publication et de Communication - All Rights Reserved
*
* Unauthorized copying of this file, via any medium is strictly prohibited by law
* This file is proprietary and confidential
*/
namespace App\Controller;
use Swift_Mailer;
use App\Entity\Ville;
use App\Entity\Region;
use App\Service\Slugify;
use App\Entity\Departement;
use App\Entity\OffreEmploi;
use App\Entity\Utilisateur;
use App\Service\PathBuilder;
use App\Common\LieuInterface;
use App\Entity\Etablissement;
use App\Service\UserTransient;
use App\Entity\OffreEmploiProfil;
use App\Service\OffreEmploiUnread;
use App\Service\MailMessageFactory;
use App\Entity\OffreEmploiCandidature;
use App\Form\OffreEmploiCandidatureType;
use App\Repository\OffreEmploiRepository;
use App\Controller\Helper\CandidatureTrait;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
final class OffreEmploiController extends AbstractController
{
use CandidatureTrait;
private const LIMIT = 2; // Nbre d'offres à afficher dans l'onglet du header
private const PER_PAGE = 30;
/** @var PaginatorInterface */
private $paginator;
/** @var OffreEmploiUnread */
private $offreEmploiNonLu;
/** @var UserTransient */
private $transient;
/** @var Swift_Mailer */
private $mailer;
/** @var MailMessageFactory */
private $mailMessageFactory;
/** @var PathBuilder */
private $pathBuilder;
/**
* @var Slugify
*/
private $slugify;
public function __construct(
PaginatorInterface $paginator,
OffreEmploiUnread $offreEmploiNonLu,
UserTransient $transient,
Swift_Mailer $mailer,
MailMessageFactory $mailMessageFactory,
PathBuilder $pathBuilder,
Slugify $slugify
) {
$this->paginator = $paginator;
$this->offreEmploiNonLu = $offreEmploiNonLu;
$this->transient = $transient;
$this->mailer = $mailer;
$this->mailMessageFactory = $mailMessageFactory;
$this->pathBuilder = $pathBuilder;
$this->slugify = $slugify;
}
/**
* @Route("/emplois",
* name="offre-emploi-root")
* @Route("/emplois/offre_emplois/{lieu}/{id}",
* name="offre-emploi-liste", defaults={"id": null, "lieu":"default"}, methods={"GET", "POST"})
* @Route("/emplois/{lieu}/{id}",
* name="offre-emploi-liste-old-2", defaults={"id": null, "lieu":"default"}, methods={"GET", "POST"})
* @Route("/offre-emploi/liste/{id}",
* name="offre-emploi-liste-old", defaults={"id": null}, methods={"GET"})
*/
public function list(Request $request, ?Etablissement $etablissement, ?string $id, string $lieu = null): Response
{
if (!$etablissement && $id) {
return $this->redirectToRoute('offre-emploi-root', [], 301);
}
$currentRoute = $request->attributes->get('_route');
if ('offre-emploi-root' != $currentRoute) {
return $this->redirectToRoute('offre-emploi-root', [], 301);
}
if ($lieu != null)
return $this->redirectToRoute('offre-emploi-root', [], 301);
$profils_list = $this->getDoctrine()->getRepository(OffreEmploiProfil::class)->findAllHavingJobs();
$profils = $request->query->get('profil');
$currentURL = $request->getPathInfo();
if ('default' != $lieu) {
$currentURL = explode('/', $currentURL);
array_pop($currentURL);
$currentURL = implode('/', $currentURL);
}
$types = [];
$ecole = [];
$college = [];
$lycee = [];
$professionnel = [];
$superieur = [];
$niveaux = $request->query->get('niveau');
$robots_tag = null;
if (isset($profils) || isset($niveaux))
$robots_tag = "noindex, follow";
if ($niveaux) {
if (in_array('ecole', $niveaux)) {
$ecole = ['02-ELEM', '03-PRIM', '01-MATER'];
}
if (in_array('college', $niveaux)) {
$college = ['04-COLL'];
}
if (in_array('lycee', $niveaux)) {
$lycee = ['05-LGEN', '06-LTECH', '07-LEGT'];
}
if (in_array('professionnel', $niveaux)) {
$professionnel = ['08-LAGRI', '09-LPROF', '10-LEAP'];
}
if (in_array('superieur', $niveaux)) {
$superieur = ['12-SUP'];
}
$types = array_merge($ecole, $college, $lycee, $professionnel, $superieur);
}
$regions = $departements = $villes = null;
/** @var OffreEmploiRepository $repository */
$repository = $this->getDoctrine()->getRepository(OffreEmploi::class);
$queryBuilder = $repository
->createQueryBuilder('o')
->orderBy('o.dateActualisation', 'DESC')
->innerJoin('o.etablissement', 'e')
->innerJoin('e.ville', 'v');
// Filter les offre valides
$repository->filterQueryWithValidOnly('o', $queryBuilder);
// Filtre par libellé
if ($profils) {
$queryBuilder
->andWhere($queryBuilder->expr()->in('o.profil', $profils));
}
// Filtre par établissement
if ($etablissement) {
$queryBuilder
->andWhere($queryBuilder->expr()->eq('o.etablissement', ':etablissement'))
->setParameter('etablissement', $etablissement);
}
// Filtre par niveau
if ($types) {
$queryBuilder
->andWhere($queryBuilder->expr()->in('e.type', $types));
}
$offres = $this->paginator->paginate(
$queryBuilder->getQuery(),
$request->query->getInt('page', 1),
self::PER_PAGE
);
$page = $request->query->getInt('page');
if ($page > $offres->getPageCount() || 1 == $page) {
return $this->redirectToRoute('offre-emploi-root', [], 301);
}
return $this->render('offre-emploi/list.html.twig', [
'lieu' => $lieu,
'etablissement' => $etablissement,
'offres' => $offres,
'regions' => $regions,
'departements' => $departements,
'villes' => $villes,
'niveaux' => $niveaux,
'profils_list' => $profils_list,
'currentURL' => $currentURL,
'profils' => $profils,
'robots_tag' => $robots_tag,
]);
}
/**
* @Route("/offre-emploi/fiche/{id}", name="offre-emploi", methods={"GET", "POST"})
*/
// * @Cache(
// * lastModified="offre.getDateActualisation()",
// * ETag="'OffreEmploi' ~ offre.getId() ~ offre.getDateActualisation().getTimestamp()",
// * expires="+5 minutes",
// * public=false
// * )
public function fiche(Request $request, OffreEmploi $offre = null): Response
{
if (null == $offre) {
$this->addFlash('success', "L'offre d'emploi a expirée ou a été supprimée !");
return $this->redirectToRoute('offre-emploi-root', [], 301);
}
if (!$offre->isValid()) {
$this->addFlash('success', "L'offre d'emploi a expirée.");
$etablissement = $offre->getEtablissement();
if ($etablissement) {
return $this->redirect(
$this->pathBuilder->buildFiche($etablissement),
Response::HTTP_MOVED_PERMANENTLY
);
}
return $this->redirectToRoute('offre-emploi-root', [], 301);
}
$candidature = new OffreEmploiCandidature();
$form = $this->createForm(OffreEmploiCandidatureType::class, $candidature);
$form->get('libelle')->setData($offre->getProfil().' '.$offre->getContrat());
$form->remove('libelle');
// Retablis valeurs
$form->get('civilite')->setData($this->transient->get(UserTransient::CIVILITE));
$form->get('nom')->setData($this->transient->get(UserTransient::NOM));
$form->get('prenom')->setData($this->transient->get(UserTransient::PRENOM));
$form->get('telephone')->setData($this->transient->get(UserTransient::TELEPHONE));
$form->get('email')->setData($this->transient->get(UserTransient::EMAIL));
$idLast = $this->transient->get(UserTransient::OFFRE_EMPLOI_CANDIDATURE);
/** @var OffreEmploiCandidature $last */
$last = $idLast ? $this->getDoctrine()->getRepository(OffreEmploiCandidature::class)->find($idLast) : null;
if ($last) {
$form->get('adresse')->setData($last->getAdresse());
$form->get('codePostal')->setData($last->getCodePostal());
$form->get('ville')->setData($last->getVille());
$form->get('commentaire')->setData($last->getCommentaire());
}
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid() && empty($form->get("email2")->getData())) {
$candidature->setOffreEmploi($offre);
$this->persisteCandidature($candidature);
$this->sendCandidatureEmail($candidature);
$this->addFlash('success', 'Votre candidature a été envoyée');
$this->saveCandidatureTransientData($candidature);
return $this->redirectToRoute(
'offre-emploi',
['id' => $offre->getId()],
Response::HTTP_FOUND
);
}
$this->offreEmploiNonLu->markAsRead($offre);
return $this->render('offre-emploi/fiche.html.twig', [
'urlCanonical' => $offre->getUrl(),
'offre' => $offre,
'form' => $form->createView(),
'lieu' => $offre->getEtablissement()->getVille(),
]);
}
/**
* @Route(
* "/offre-emploi/header",
* name="offre-emploi-header",
* methods={"GET"}
* )
* @Cache(expires="+1 minutes")
*/
public function headerList(LieuInterface $lieu = null): Response
{
// Afficher les 2 derniers items en se basant sur la géoloc, on cherche dans ville sinon on monte plus haut
$items = null;
// dump($lieu);
if ($lieu and $lieu->getSlug() != "default") {
$items = $this->getDoctrine()->getRepository(OffreEmploi::class)->findByLieu($lieu);
// dump($items);
if ($lieu instanceof Ville && count($items) <= 1) {
$lieu = $lieu->getDepartement();
$items = $this->getDoctrine()->getRepository(OffreEmploi::class)->findByLieu($lieu);
// dump($items);
if (count($items) <= 1) {
$lieu = $lieu->getRegion();
$items = $this->getDoctrine()->getRepository(OffreEmploi::class)->findByLieu($lieu);
// dump($items);
}
} elseif ($lieu instanceof Departement && count($items) <= 1) {
$lieu = $lieu->getRegion();
$items = $this->getDoctrine()->getRepository(OffreEmploi::class)->findByLieu($lieu);
// dump($items);
} elseif(count($items) <= 1) { // région
$items = $this->getDoctrine()->getRepository(OffreEmploi::class)->findByLieu($lieu);
// dump($items);
}
}
if (empty($items)) { // toutes les items
$items = $this->getDoctrine()->getRepository(OffreEmploi::class)->findBy(
[],
['dateCreation' => 'DESC'],
self::LIMIT
);
// dump($items);
}
return $this->render('offre-emploi/dropdown.html.twig', [
'offres' => $items,
]);
}
/**
* Renvoi la liste (tableau) de destinataires Emploi, par défaut (si aucun argument) toutes les @ du module contact
*
* @param string $role renvoyer uniquement les @ ayant le role indiqué, éventuellement si c'est un responsable, on se limite à ceux ayant accepté leur @ comme défaut
* @param bool $forceResponsable ignorer le dernier pt du param précédent : c-a-d on ignore si le responsable a décoché son adr en tant que destinataire par défaut
*/
private function getDestinatairesCandidature($etablissement, string $role = null, bool $forceResponsable = null)
{
$etabs = [];
$emails = [];
$responsables = $this->getDoctrine()
->getRepository(Utilisateur::class)
->findResponsablesByEtablissement($etablissement);
foreach ($responsables as $responsable) {
$etabs = $responsable->getEtablissementsResponsable();
}
$responsables = $this->getDoctrine()
->getRepository(Utilisateur::class)
->findResponsablesByEtablissements($etabs);
foreach ($responsables as $responsable) {
if (
(!$role || $role == "ROLE_RESPONSABLE_ETABLISSEMENT") and
$responsable->hasRole('ROLE_RESPONSABLE_ETABLISSEMENT') and
($forceResponsable or $responsable->isMailCandidatureOffreEmploi())
) {
$emails[] = $responsable->getEmail();
}
if (
(!$role || $role == "ROLE_EMPLOI") and
$responsable->hasRole('ROLE_EMPLOI')
) {
$emails[] = $responsable->getEmail();
}
}
return !empty($emails) ? $emails : null;
}
}