src/Controller/Page/VacancyController.php line 136

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Page;
  3. use App\Entity\Company;
  4. use App\Entity\Option;
  5. use App\Entity\Site;
  6. use App\Entity\Vacancy;
  7. use App\Event\VacancyEvent;
  8. use App\Exception\UserExistsException;
  9. use App\Form\BaseVacancyCompanyType;
  10. use App\Form\VacancyFormDecorator;
  11. use App\Model\Vacancy\VacancyWrapper;
  12. use App\Renderer\Page;
  13. use App\Renderer\VacancyRenderer;
  14. use App\Service\UserService;
  15. use App\Service\VacancyService;
  16. use Doctrine\ORM\EntityManagerInterface;
  17. use Flagception\Manager\FeatureManagerInterface;
  18. use FOS\HttpCacheBundle\Configuration\Tag;
  19. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  20. use Symfony\Component\Form\FormError;
  21. use Symfony\Component\HttpFoundation\Request;
  22. use Symfony\Component\HttpFoundation\Response;
  23. use Symfony\Component\HttpKernel\Exception\HttpException;
  24. use Symfony\Component\Routing\Annotation\Route;
  25. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  26. use Symfony\Contracts\Translation\TranslatorInterface;
  27. use Twig\Error\LoaderError;
  28. use Twig\Error\RuntimeError;
  29. use Twig\Error\SyntaxError;
  30. #[Route(path'/vacature')]
  31. class VacancyController extends AbstractController
  32. {
  33.     public const URL_PARAM_COVID_19 'covid-19';
  34.     private Page $pageRenderer;
  35.     private VacancyService $service;
  36.     private VacancyFormDecorator $vacancyFormDecorator;
  37.     private FeatureManagerInterface $featureManager;
  38.     private UserService $userService;
  39.     private TranslatorInterface $translator;
  40.     private EventDispatcherInterface $eventDispatcher;
  41.     private VacancyRenderer $vacancyRenderer;
  42.     public function __construct(
  43.         Page $pageRenderer,
  44.         VacancyService $service,
  45.         VacancyFormDecorator $vacancyFormDecorator,
  46.         FeatureManagerInterface $featureManager,
  47.         UserService $userService,
  48.         TranslatorInterface $translator,
  49.         EventDispatcherInterface $eventDispatcher,
  50.         VacancyRenderer $vacancyRenderer
  51.     ) {
  52.         $this->pageRenderer $pageRenderer;
  53.         $this->service $service;
  54.         $this->vacancyFormDecorator $vacancyFormDecorator;
  55.         $this->featureManager $featureManager;
  56.         $this->userService $userService;
  57.         $this->translator $translator;
  58.         $this->eventDispatcher $eventDispatcher;
  59.         $this->vacancyRenderer $vacancyRenderer;
  60.     }
  61.     #[Route(path'/solliciteer/{id}'name'external_apply_action')]
  62.     public function externalAction(Request $requestint|string $id): Response
  63.     {
  64.         $request->query->add(['apply' => 1]);
  65.         return $this->detailWithExternalId($request$id);
  66.     }
  67.     /**
  68.      * @Tag("vacancies", expression="'vacancies-'~id")
  69.      *
  70.      * @param int|string $id the external id
  71.      */
  72.     #[Route(path'/external/{id}'name'vacancy_detail_external_id'options: ['expose' => true])]
  73.     public function detailWithExternalId(Request $requestint|string $id): Response
  74.     {
  75.         $vacancy $this->getDoctrine()->getRepository(Vacancy::class)
  76.             ->findOneBy(['externalId' => $id])
  77.         ;
  78.         if (!$vacancy) {
  79.             $vacancy $this->getDoctrine()->getRepository(Vacancy::class)
  80.                 ->findOneBy(['externalReference' => $id])
  81.             ;
  82.         }
  83.         if (!$vacancy) {
  84.             $vacancy $this->getDoctrine()->getRepository(Vacancy::class)
  85.                 ->findOneBy(['displayableExternalId' => $id])
  86.             ;
  87.         }
  88.         if (!$vacancy) {
  89.             throw new HttpException('404');
  90.         }
  91.         $routeParams array_merge([
  92.             'id' => $vacancy->getId(),
  93.             'slug' => $vacancy->getSlug(),
  94.         ], $request->query->all());
  95.         return $this->redirectToRoute('vacancy_detail'$routeParams);
  96.     }
  97.     /**
  98.      * @Tag("vacancies")
  99.      * @Tag("vacancy-detail", expression="'vacancies-'~id")
  100.      *
  101.      * @throws LoaderError
  102.      * @throws RuntimeError
  103.      * @throws SyntaxError
  104.      */
  105.     public function detailAction(Request $request): Response
  106.     {
  107.         $vacancyWrapper $this->service->getVacancyFromRequest($request);
  108.         $vacancy $vacancyWrapper?->vacancy;
  109.         if ($vacancyWrapper && $externalDetailUrl $vacancyWrapper->vacancy->getExternalDetailUrl()) {
  110.             return $this->redirect($externalDetailUrl);
  111.         }
  112.         // If no vacancy wrapper is created, vacancy is not found
  113.         if (!$vacancyWrapper instanceof VacancyWrapper) {
  114.             throw $this->createNotFoundException();
  115.         }
  116.         // If FEATURE_TRANSLATION is enabled, vacancy.title can be falsy which means the vacancy is untranslated
  117.         if (!(bool) $vacancy?->getTitle()) {
  118.             throw $this->createNotFoundException();
  119.         }
  120.         return $this->vacancyRenderer
  121.             ->renderDetail(
  122.                 $request,
  123.                 $vacancyWrapper
  124.             )
  125.         ;
  126.     }
  127.     /**
  128.      * @throws LoaderError
  129.      * @throws RuntimeError
  130.      * @throws SyntaxError
  131.      */
  132.     public function create(Request $request, array $config = []): Response
  133.     {
  134.         if (!$this->featureManager->isActive('feature_vacancy_without_account')) {
  135.             return $this->redirectToRoute('homepage');
  136.         }
  137.         $isCovidVacancy = !empty($config[self::URL_PARAM_COVID_19]) ? $config[self::URL_PARAM_COVID_19] : false;
  138.         /** @var Option $covidOption */
  139.         $covidOption $this->getDoctrine()->getRepository(Option::class)->findOneBy([
  140.             'internalName' => self::URL_PARAM_COVID_19,
  141.         ]);
  142.         $site null;
  143.         if ($siteId $request->get('site')) {
  144.             $site $this->getDoctrine()->getRepository(Site::class)->find($siteId);
  145.         }
  146.         $vacancy = new Vacancy();
  147.         $form $this->createForm(BaseVacancyCompanyType::class, null, [
  148.             'decorator' => $this->vacancyFormDecorator,
  149.             'vacancy' => $vacancy,
  150.             'site' => $site,
  151.             'action' => $this->generateUrl($isCovidVacancy 'vacancy_create_without_account_covid' 'vacancy_create_without_account'$request->query->all()),
  152.             'covid' => $isCovidVacancy,
  153.         ]);
  154.         $form->handleRequest($request);
  155.         if ($form->isSubmitted()) {
  156.             if ($form->isValid()) {
  157.                 /**
  158.                  * @var Vacancy $vacancy
  159.                  * @var Company $company
  160.                  */
  161.                 $vacancy $form->get('vacancy')->getData();
  162.                 if ($isCovidVacancy && !$covidOption->getValues()->isEmpty()) {
  163.                     $vacancy $vacancy
  164.                         ->addOptionValue($covidOption->getValues()->first())
  165.                     ;
  166.                 }
  167.                 $company $form->get('company')->getData();
  168.                 $email $company->getEmail();
  169.                 $vacancy->setActive(false);
  170.                 $vacancy->setCompany($company);
  171.                 try {
  172.                     $user $this->userService->createUserFromEmail(
  173.                         $email,
  174.                         ['ROLE_SITE_COMPANY_USER'],
  175.                         true,
  176.                         $config
  177.                     );
  178.                     $entityManager $this->getDoctrine()->getManager();
  179.                     if ($state $entityManager->getFilters()->isEnabled('softdeleteable')) {
  180.                         $entityManager->getFilters()->disable('softdeleteable');
  181.                     }
  182.                     $entityManager->persist($company);
  183.                     $entityManager->persist($vacancy);
  184.                     $entityManager->flush();
  185.                     $user->addCompany($company);
  186.                     $entityManager->persist($user);
  187.                     $entityManager->flush();
  188.                     if ($state) {
  189.                         $entityManager->getFilters()->enable('softdeleteable');
  190.                     }
  191.                     $this->eventDispatcher->dispatch(
  192.                         new VacancyEvent($vacancy),
  193.                         VacancyEvent::VACANCY_CREATED_WITHOUT_ACCOUNT
  194.                     );
  195.                     // redirect to thanks page
  196.                     try {
  197.                         return $this->redirectToRoute('vacancy_create_without_account_thanks', ['v' => $vacancy->getId()]);
  198.                     } catch (\Exception) {
  199.                         $route 'vacancy_create_without_account';
  200.                         if ($isCovidVacancy) {
  201.                             $route 'vacancy_create_without_account_covid';
  202.                         }
  203.                         return $this->redirectToRoute($route);
  204.                     }
  205.                 } catch (UserExistsException) {
  206.                     $form->get('company')
  207.                         ->get('email')
  208.                         ->addError(
  209.                             new FormError($this->translator->trans('User already exists'))
  210.                         );
  211.                 }
  212.             }
  213.             $this->addFlash('danger'$this->translator->trans('Cannot create vacancy'));
  214.         }
  215.         $response $this->pageRenderer
  216.             ->renderPage(
  217.                 '{vacancy_create}',
  218.                 '@default/pages/create_vacancy.html.twig',
  219.                 [
  220.                     'form' => $form->createView(),
  221.                     'isCovid' => $isCovidVacancy,
  222.                 ]
  223.             );
  224.         $response->setSharedMaxAge(0);
  225.         return $response;
  226.     }
  227.     /**
  228.      * @throws LoaderError
  229.      * @throws RuntimeError
  230.      * @throws SyntaxError
  231.      */
  232.     public function thanks(Request $requestEntityManagerInterface $entityManager): Response
  233.     {
  234.         $vacancyID $request->get('v');
  235.         $vacancy $entityManager->getRepository(Vacancy::class)->find($vacancyID);
  236.         if (!$vacancy instanceof Vacancy) {
  237.             throw $this->createNotFoundException();
  238.         }
  239.         $response $this->pageRenderer
  240.             ->renderPage(
  241.                 '{vacancy_create_thanks}',
  242.                 '@default/pages/create_vacancy_thanks.html.twig',
  243.                 ['vacancy' => $vacancy]
  244.             );
  245.         $response->setSharedMaxAge(0);
  246.         return $response;
  247.     }
  248. }