<?php
namespace App\Controller\Back;
use App\Adapter\AdminViewAdapter;
use App\Entity\User;
use App\Factories\UserFactory;
use App\Form\CustomExportForm;
use App\Form\RegistrationModifyFormType;
use App\Form\User\AdminUserType;
use App\Form\User\UserEditType;
use App\Form\User\UserMdpEditType;
use App\Logger\UserLoggerHistory;
use App\Repository\UserRepository;
use App\Utils\CsvUserCreator;
use App\Utils\DateCalculator;
use App\Utils\Mailer;
use Doctrine\ORM\EntityManagerInterface;
use OpenApi\Annotations as OA;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* @Route("/admin/user")
*
* @OA\Tag(name="Admin BO - User")
*/
class UserController extends AbstractController
{
private UserRepository $userRepo;
private EntityManagerInterface $em;
private SerializerInterface $serializer;
private UserLoggerHistory $userLoggerHistory;
private DateCalculator $dateCalculator;
private UserFactory $userFactory;
private TranslatorInterface $translator;
public function __construct(
UserRepository $userRepository,
EntityManagerInterface $entityManager,
SerializerInterface $serializer,
UserLoggerHistory $userLoggerHistory,
DateCalculator $dateCalculator,
UserFactory $userFactory,
TranslatorInterface $translator
) {
$this->userRepo = $userRepository;
$this->em = $entityManager;
$this->serializer = $serializer;
$this->userLoggerHistory = $userLoggerHistory;
$this->dateCalculator = $dateCalculator;
$this->userFactory = $userFactory;
$this->translator = $translator;
}
/**
* Administrators list.
*
* @Route(
* "/listeAdmin",
* name="liste_user",
* methods={"GET"}
* )
*/
public function admins(): Response
{
$admins = array_map(function (User $admin) {
$admin = new AdminViewAdapter($admin);
$admin->setActions(
[
'isActive' => 0 === array_search('ROLE_INACTIF', $admin->getRoles()),
'edit' => $this->generateUrl('user_edit', [
'id' => (string) $admin->getId(),
]),
'password' => $this->generateUrl('user_send_password_mail', [
'id' => (string) $admin->getId(),
]),
'delete' => $this->generateUrl('user_delete', [
'id' => (string) $admin->getId(),
]),
]
);
return $admin;
}, $this->userRepo->findAllAdmins());
return $this->render(
'user/admin/administrateurs.html.twig',
['administrateurs' => $this->serializer->serialize($admins, 'json')]
);
}
/**
* Send another email to admin.
*
* @Route(
* "/{id}/mail",
* name="user_send_password_mail",
* methods={"GET"}
* )
*/
public function resendMailAdminPassword(
User $user,
Mailer $mailer
): Response {
$user->setEmailAuthCode(bin2hex(random_bytes(16)));
$this->em->persist($user);
$this->em->flush();
try {
$mailer->sendAdminCreationMail($user);
} catch (\Exception $e) {
$this->addFlash('danger', 'danger.' . $e->getMessage());
return $this->redirectToRoute('liste_user');
}
$this->userLoggerHistory->logAdmin(
$user,
$this->getUser(),
'resend mail password'
);
$this->addFlash('success', 'success.resendPassword');
return $this->redirectToRoute('liste_user');
}
/**
* Create a user.
*
* @Route(
* "/create",
* name="user_create",
* methods={"GET", "POST"}
* )
*/
public function create(
Request $request,
Mailer $mailer
): Response {
$user = $this->userFactory->createAdminUser();
$user->setEmailAuthCode(bin2hex(random_bytes(16)));
$user->setDoubleauth(0);
$form = $this->createForm(
AdminUserType::class,
$user,
['type' => 'create']
);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user->setPassword('todefine');
$user->setIsActive(false);
$this->em->persist($user);
$this->em->flush();
$this->userLoggerHistory->logAdmin(
$user,
$this->getUser(),
'Création'
);
$mailer->sendAdminCreationMail($user);
$this->addFlash('success', 'success.adminRegistered');
return $this->redirectToRoute('liste_user');
}
return $this->render(
'user/admin/create.html.twig',
['form' => $form->createView()]
);
}
/**
* Create a user.
*
* @Route(
* "/edit/{id}",
* name="user_edit",
* methods={"GET", "POST"}
* )
*/
public function edit(
Request $request,
User $user
): Response {
$this->userLoggerHistory->addHistory([
'roles',
'getemail',
'doubleauth',
]);
$this->userLoggerHistory->setOldReference($user);
$type = 'edit';
$form = $this->createForm(UserEditType::class, $user, [
'type' => $type,
]);
$form->get('doubleauth')->setData($user->getDoubleauth());
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// Valid user modification
$user->setDeletedAt(null);
$user->setDoubleauth($form->get('doubleauth')->getData());
$this->em->flush();
$this->userLoggerHistory->setNewReference($user);
/** @var User $modifier */
$modifier = $this->getUser();
$this->userLoggerHistory->persistDiff(
$modifier,
$user
);
// for now
return $this->redirectToRoute('liste_user');
}
return $this->render(
'user/admin/edit.html.twig',
[
'form' => $form->createView(),
'user' => $user,
]
);
}
/**
* Delete a user.
*
* @Route(
* "/delete/{id}",
* name="user_delete",
* methods={"GET"}
* )
*/
public function delete(User $user): Response
{
if (null === $this->getUser()) {
return $this->redirectToRoute('liste_user');
}
$user->setUsername(null);
$user->setDeletedAt($this->dateCalculator->getDatetimeNow());
$user->setRoles(['ROLE_INACTIF']);
// TODO Set role inactif
// Historique actions user
$this->userLoggerHistory->logAdmin(
$user,
$this->getUser(),
'Suppression'
);
return $this->redirectToRoute('liste_user');
}
/**
* User account details.
*
* @Route(
* "/mon_compte",
* name="user_my_account",
* methods={"GET", "POST"}
* )
*/
public function monCompte(Request $request): Response
{
/** @var User $user */
$user = $this->getUser();
$this->userLoggerHistory->setOldReference($user);
$form = $this->createForm(
RegistrationModifyFormType::class,
$this->getUser()
);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->userLoggerHistory->setNewReference($user);
$this->userLoggerHistory->persistDiff($user, $user);
return $this->redirectToRoute('user_my_account');
}
return $this->render(
'user/admin/moncompte.html.twig',
['form' => $form->createView()]
);
}
/**
* Change password.
*
* @Route(
* "/change_password/{id}",
* name="user_change_password",
* methods={"GET", "POST"}
* )
*/
public function changePassword(
Request $request,
User $user,
UserPasswordHasherInterface $passwordHasher
): Response {
/** @var User $userSymfony */
$userSymfony = $this->getUser();
if (
!$this->isGranted('ROLE_ADMIN')
&& $user->getId() !== $userSymfony->getId()
) {
throw new AccessDeniedException();
}
$form = $this->createForm(UserMdpEditType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$mdp = $form->get('password')->getData();
if (null !== $mdp) {
$hashedPassword = $passwordHasher->hashPassword(
$user,
$mdp
);
$user->setPassword($hashedPassword);
$this->em->flush();
}
// Historique actions user
/** @var User $modifier */
$modifier = $this->getUser();
$this->userLoggerHistory->logHistoryModification(
$user,
$modifier,
'password'
);
return $this->redirectToRoute('logout');
}
return $this->render(
'user/admin/monpassword.html.twig',
['form' => $form->createView()]
);
}
/**
* Create CSV for Admin with custom header.
*
* @Route(
* "/exportPersoAdmin",
* name="export_perso_admin",
* methods={"GET", "POST"}
* )
*/
public function exportPersoAdmin(
Request $request,
CsvUserCreator $csvUserCreator
): Response {
$choices = [
'Login' => 'Username',
'Email' => 'Email',
'Profil' => 'Roles',
];
$form = $this->createForm(CustomExportForm::class, null, [
'choices' => $choices,
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$exportCSV = $request->query->get('exportCuCSV');
if ($exportCSV) {
$admins = $this->userRepo->findAllNotCustomer();
$csvUserCreator->setFileName('administrateurs');
$csvUserCreator->setHeaders(
$form->get('choices')->getData(),
array_flip($choices)
);
$csvUserCreator->setData($admins);
return $csvUserCreator->downloadCSV();
}
}
return $this->render(
'user/admin/exportAdmin.html.twig',
['form' => $form->createView()]
);
}
/**
* Allows you to send custom email to a list of users.
*
* @Route(
* "/send-custom-email",
* name="send_custom_email",
* methods={"POST"}
* )
*/
public function sendCustomEmailToUsers(
Request $request,
Mailer $mailer
): JsonResponse {
$recipients = $request->get('recipients');
$subject = $request->get('subject');
$body = $request->get('body');
$lignes = explode("\n", $body);
try {
$mailer->sendCustomEmail($recipients, $subject, $lignes);
} catch (\Exception $e) {
return new JsonResponse([
'status' => 'error',
'message' => $this->translator->trans(
'danger.error',
[],
'flashes'
) . ' : ' . $e->getMessage(),
]);
}
return new JsonResponse([
'status' => 'success',
'message' => $this->translator->trans(
'success.emailSent',
[],
'flashes'
),
]);
}
}