<?php
namespace App\Controller;
use Knp\Snappy\Pdf;
use App\Entity\User;
use App\Entity\Media;
use App\Service\Mail;
use App\Entity\Newsletter;
use App\Entity\Contributor;
use App\Entity\Instance;
use App\Entity\ContributorConfig;
use App\Service\SiteConfig;
use App\Form\NewsletterType;
use App\Form\ContributorType;
use App\Repository\UserRepository;
use App\Service\ItmConnectApiService;
use App\Repository\BlogPostRepository;
use App\Repository\NewsletterRepository;
use Doctrine\ORM\EntityManagerInterface;
use App\Repository\ContactConfigRepository;
use Symfony\Component\HttpFoundation\Request;
use App\Repository\BlogPostCategoryRepository;
use App\Repository\Criteria1ItemRepository;
use App\Repository\Criteria1Repository;
use App\Repository\Criteria2ItemRepository;
use App\Repository\Criteria2Repository;
use App\Repository\Criteria3ItemRepository;
use App\Repository\Criteria3Repository;
use App\Service\ldapV2NettoService;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Profiler\Profiler;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\String\Slugger\SluggerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use App\Repository\SiteConfigRepository;
class HomeController extends AbstractController
{
/**
* HomeController constructor.
* @param BlogPostRepository $blogPostRepository
* @param BlogPostCategoryRepository $blogPostCategoryRepository
*/
public function __construct(
private BlogPostRepository $blogPostRepository,
private BlogPostCategoryRepository $blogPostCategoryRepository,
private Pdf $pdf,
private EntityManagerInterface $entityManager,
private SluggerInterface $slugger,
private RouterInterface $router,
private TranslatorInterface $translator,
private UserRepository $userRepository,
private UserPasswordHasherInterface $userPasswordHasher,
private ItmConnectApiService $itmconnect,
private UrlGeneratorInterface $urlGenerator,
private Mail $mail,
private SiteConfig $config,
private EntityManagerInterface $em,
private ContactConfigRepository $contactConfigRepo,
private HttpClientInterface $client,
private Criteria1ItemRepository $criteria1ItemRepository,
private Criteria2ItemRepository $criteria2ItemRepository,
private Criteria3ItemRepository $criteria3ItemRepository,
private LoggerInterface $logger,
private ldapV2NettoService $ldapV2NettoService,
private SiteConfigRepository $siteConfigRepository,
) {
$generalSiteConfig = $this->siteConfigRepository->findOneBy([]);
$isInstanceActive = $generalSiteConfig ? $generalSiteConfig->isInstanceActive() : true;
if($isInstanceActive) {
$this->config->getConfig();
$this->config->getCustomization();
}
}
/**
* @Route("/", name="home")
*/
public function home(?Profiler $profiler, Request $request): Response
{
if (!$this->getUser() && !$this->config->isPublicFrontOffice()) {
return $this->redirectToRoute('app_login');
}
$user = $this->getUser();
$session = $request->getSession();
if ($user && $user->getInstances()->count() > 0) {
$selectedInstanceId = $session->get('selected_instance_id');
if ($user->getInstances()->count() === 1 && !$selectedInstanceId) {
$instance = $user->getInstances()->first();
$session->set('selected_instance_id', $instance->getId());
$this->config->getConfig();
$this->config->getCustomization();
$selectedInstanceId = $instance->getId();
}
if (!$selectedInstanceId) {
// Get the last selected instance from session to pre-select it
$lastSelectedInstanceId = $session->get('last_selected_instance_id');
return $this->render('home/partials/select_instance.html.twig', [
'instances' => $user->getInstances(),
'selected_instance_id' => $lastSelectedInstanceId,
]);
}
}
return $this->render('home/index.html.twig', $this->homeData($profiler, $request));
}
/**
* @Route("/select-instance", name="select_instance", methods={"POST"})
*/
public function selectInstance(Request $request): Response
{
$instanceId = $request->request->get('instance_id');
$session = $request->getSession();
$session->set('selected_instance_id', $instanceId);
return $this->redirectToRoute('home');
}
/**
* @Route("/clear-instance", name="clear_instance")
*/
public function clearInstance(Request $request): Response
{
$session = $request->getSession();
$currentInstanceId = $session->get('selected_instance_id');
if ($currentInstanceId) {
$session->set('last_selected_instance_id', $currentInstanceId);
}
$session->remove('selected_instance_id');
return $this->redirectToRoute('home');
}
#[Route("/fr")]
public function fr()
{
return $this->redirectToRoute('home');
}
#[Route("/fr/admin")]
public function frAdmin()
{
return $this->redirectToRoute('home');
}
/**
* @Route("/api/oauth2/", name="oauth2_api")
*/
public function apiLogin(Request $request): Response
{
/** @var User $user */
$user = $this->getUser();
// Manually authenticate the user
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
$this->get('session')->set('_security_main', serialize($token));
return $this->redirectToRoute('home');
}
/**
* @Route("/api/logout/", name="oauth2_logout")
* @throws \Doctrine\DBAL\Exception
*/
public function apiLogout(Request $request): Response
{
/** @var User $user */
$user = $this->getUser();
if ($user) {
$conn = $this->em->getConnection();
$sqlToken = "select identifier from oauth2_access_token where oauth2_access_token.user_identifier = :identifier";
$stmtToken = $conn->prepare($sqlToken);
$results = $stmtToken->executeQuery(['identifier' => $user->getUserIdentifier()]);
$token = $results->fetchAssociative();
if ($token) {
// Delete refresh token
$sqlDeleteRefreshToken = "delete from oauth2_refresh_token where oauth2_refresh_token.access_token = :token";
$stmtDeleteRefreshToken = $conn->prepare($sqlDeleteRefreshToken);
$stmtDeleteRefreshToken->executeQuery(['token' => $token['identifier']]);
// Delete access token
$sqlDeleteToken = "delete from oauth2_access_token where oauth2_access_token.user_identifier = :identifier";
$stmtDeleteToken = $conn->prepare($sqlDeleteToken);
$stmtDeleteToken->executeQuery(['identifier' => $user->getUserIdentifier()]);
}
}
return $this->json([
'message' => 'You successfully logged out',
]);
}
/**
* @Route("/acceptCgu", name="accept_cgu", methods={"GET"})
*/
public function acceptCgu(Request $request): JsonResponse
{
$user = $this->getUser();
if (!$user) {
return new JsonResponse(['success' => false]);
}
$user->setAcceptCgu(true);
$this->em->persist($user);
$this->em->flush();
return new JsonResponse(['success' => true]);
}
/**
* @Route("/itmconnect", name="itmconnect")
*/
public function ItmConnect(Request $request): Response
{
return $this->redirect($this->itmconnect->buildAuthorizeUrl());
}
/**
* @Route("/authorization-code/callback", name="callback")
*/
public function callback(Request $request)
{
$data = $this->itmconnect->authorizeUser();
$token = $data['token'];
$refresh_token = $data['refresh_token'];
if (!$token) {
return $this->redirectToRoute('home');
}
if (property_exists($token, 'email')) {
$email = $token->email;
} else {
$email = $token->preferred_username;
}
$user = $this->userRepository->findOneBy(['email' => $email]);
if (!$user) {
$user = new User();
$roles = [];
if ($token->typeUtilisateur == 'Amont') {
$roles[] = "ROLE_AMONT";
} elseif ($token->typeUtilisateur == 'adherent') {
$roles[] = "ROLE_ADHERENT";
} else {
$roles[] = "ROLE_COLLAB";
}
if (property_exists($token, 'profil')) {
if ($token->profil == "responsable_im") $roles[] = "ROLE_RESPONSABLE";
if ($token->profil == "dirigeant_im") $roles[] = "ROLE_DIRIGEANT";
if ($token->profil == "collaborateur_im") {
if (array_key_exists('ROLE_COLLAB', $roles)) {
$roles[] = "ROLE_COLLAB";
}
}
}
$user->setRoles($roles);
$user->setEmail($email);
$hash = $this->userPasswordHasher->hashPassword($user, $token->session_state);
$user->setPassword($hash);
$user->setRefreshToken($refresh_token);
$user->setIsItmConnect($hash);
$this->userRepository->addAllPreferences($user);
} else {
$user->setRefreshToken($refresh_token);
}
// ft/440_web_service_netto
if (property_exists($token, 'codeConsoFiliale')) {
$codesConsoFiliale = $token->codeConsoFiliale;
$this->ldapV2NettoService->retreiveCriteriasForUser($user, $codesConsoFiliale);
} else {
$this->logger->warning("No codeConsoFiliale can be found in the itmConnect WS");
}
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
// Manually authenticate the user
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
$this->get('session')->set('_security_main', serialize($token));
$session = $request->getSession();
$url = $this->urlGenerator->generate('home');
if ($session->get('customReferrer'))
$url = $session->get('customReferrer');
$session->remove('customReferrer');
// ft/567_password_user_memorisation_time
sleep(5);
return new RedirectResponse($url);
}
/**
* @Route("/contributor", name="contributor")
*/
public function addContributor(Request $request)
{
$contributor = new Contributor();
if ($this->getUser())
$contributor->setUser($this->getUser());
$message = $this->translator->trans('contributor.flash-message.add-contributor.done');
if ($this->config->getConfirmationMessage() != null)
$message = $this->config->getConfirmationMessage();
$form = $this->createForm(ContributorType::class, $contributor);
$form->handleRequest($request);
if ($request->getMethod() == 'POST' && $form->isSubmitted() && $form->isValid()) {
$contributor = $form->getData();
// Set the labels to save it into the contribution
$contributorConfig = $this->entityManager->getRepository(ContributorConfig::class)->findOneBy([]);
$contributor->setLabel1($contributorConfig->getFieldLabel());
$contributor->setLabel2($contributorConfig->getField2Label());
$contributor->setLabel3($contributorConfig->getField3Label());
$contributor->setLabel4($contributorConfig->getField4Label());
$contributor->setLabel5($contributorConfig->getField5Label());
$contributor->setLabel6($contributorConfig->getField6Label());
$contributor->setLabel7($contributorConfig->getField7Label());
$contributor->setLabelTextarea($contributorConfig->getTextareaLabel());
$contributor->setLabelMedia($contributorConfig->getMediaLabel());
$generalSiteConfig = $this->siteConfigRepository->findOneBy([]);
$isInstanceActive = $generalSiteConfig ? $generalSiteConfig->isInstanceActive() : true;
if ($isInstanceActive) {
$session = $request->getSession();
$instanceId = $session->get('selected_instance_id');
if ($instanceId) {
$instance = $this->entityManager->getRepository(Instance::class)->find($instanceId);
if ($instance) {
$contributor->setInstance($instance);
}
}
}
// On récupère les fichiers transmis
if ($form->has('media')) {
$files = $form->get('media')->getData();
foreach ($files as $file) {
$media = new Media();
// generate a new filename
$fileName = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME) . '-' . md5(uniqid()) . '.' . $file->guessExtension();
$fileName = preg_replace('/\s/i', '_', $fileName);
$media->setFilename($fileName);
// set your uploads directory
$uploadDir = $this->getParameter('uploads_directory');
if (!file_exists($uploadDir) && !is_dir($uploadDir)) {
mkdir($uploadDir, 0775, true);
}
$new_file = $file->move($uploadDir, $fileName);
$media->setFile($new_file);
$this->entityManager->persist($media);
$contributor->addMedia($media);
}
}
$this->entityManager->persist($contributor);
$this->entityManager->flush();
$this->addFlash('success', $message);
$subject = "Nouveau contributeur";
$content = "Un nouveau contributeur vient de s'inscrire sur le site.";
// ft/531_desable_mail_sendingblue
// $this->mail->sendingblue_email($subject, $content, $this->config->getContributionTemplateId());
}
$referer = $request->headers->get('referer');
if ($referer == null)
return $this->redirectToRoute('home');
$refererPathInfo = $request::create($referer)->getPathInfo();
$routeInfos = $this->router->match($refererPathInfo);
$route = $routeInfos['_route'];
unset($routeInfos['_route']);
unset($routeInfos['_controller']);
return $this->redirectToRoute($route, $routeInfos);
}
/**
* @Route("/subscribe-newsletter", name="subscribe_newsletter")
*/
public function subscribeNewsletter(Request $request, NewsletterRepository $newsletterRepo)
{
$formEntity = new Newsletter();
$form = $this->createForm(NewsletterType::class, $formEntity);
if ($request->isMethod('POST')) {
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$formEntity = $form->getData();
if (!$newsletterRepo->findOneBy(['email' => $formEntity->getEmail()])) {
$this->em->persist($formEntity);
$this->em->flush();
}
$this->addFlash(
'success_newsletter',
$this->translator->trans('newsletter.flash-message.subscribe.done')
);
$referer = $request->headers->get('referer');
return $this->redirect($referer); // return to previous page
}
}
// if GET render full page with form
return $this->redirectToRoute('home');
}
private function homeData($profiler, $request)
{
$preview = $request->query->getInt('preview', 0);
if ($preview && null !== $profiler) {
$profiler->disable();
}
$user = $this->getUser();
if ($user) {
$slides = $this->blogPostRepository->getSlidesForUser($user, $request);
$categories = $this->blogPostCategoryRepository->getBlogPostCategoryForUser($user, $request);
} else {
$slides = $this->blogPostRepository->getSlidesActiveAndPublic();
$categories = $this->blogPostCategoryRepository->getBlogPostCategoryByIsPublic();
}
return [
'slides' => $slides,
'categories' => $categories,
'preview' => $preview,
];
}
}