<?php
namespace App\Controller;
use App\Entity\User;
use App\Form\UserType;
use App\Entity\Mailling;
use App\Entity\Dashboard;
use App\Form\DashboardType;
use App\Notification\MaillingNotification;
use App\Repository\NoteRepository;
use App\Repository\UserRepository;
use App\Service\Calendar;
use DateTime;
use DateTimeInterface;
use Doctrine\ORM\EntityManagerInterface;
use Dotenv\Dotenv;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
/**
* @Route("/user")
*/
class UserController extends AbstractController
{
public $passwordHasher;
public $maillingNotification;
public $em;
public function __construct(UserPasswordHasherInterface $passwordHasher, MaillingNotification $maillingNotification, EntityManagerInterface $em)
{
$this->passwordHasher = $passwordHasher;
$this->em = $em;
$this->maillingNotification = $maillingNotification;
}
/**
*@Route("/", name="user.index", methods={"GET", "POST"})
*/
public function index(Request $request, UserRepository $userRepository, PaginatorInterface $paginator)
{
if (!in_array('ROLE_MASTER', $this->getUser()->getRoles())) {
return $this->redirectToRoute('dashboard.index', [], Response::HTTP_SEE_OTHER);
}
$search = trim($request->query->get('search') ?? '');
if ($request->request->get('search')) {
$search = trim($request->request->get('search'));
}
$users = $paginator->paginate(
$userRepository->findAllUsers($search),
$request->query->getInt('page', 1),
20
);
if ($request->isXmlHttpRequest()) {
return new JsonResponse([
'users' => $this->renderView('user/user_tab.html.twig', ['users' => $users]),
]);
}
return $this->render('user/index.html.twig', [
'users' => $users,
'current_page' => 'user'
]);
}
/**
*@Route("/analytics", name="user.analytics")
*/
public function analytics(Request $request, UserRepository $userRepository)
{
$userID = $request->query->get('user') ?? null;
$users = $userRepository->getStatsInfo($userID);
$pages = [];
extract($this->getStats($users, 'all'));
$pages = [];
foreach ($users_stats as $stats) {
$sums = array();
foreach (array_keys($pages + $stats) as $key) {
if (array_key_exists($key, $pages) and $pages[$key] != null) {
if (!is_string($pages[$key])) {
$sums[$key] = @($pages[$key] + $stats[$key]);
}
} else {
$sums[$key] = $stats[$key];
}
}
$pages = $sums;
}
$name = '';
if ($userID != null && !empty($pages)) {
$name = $pages['firstName'] . ' ' . $pages['name'];
}
unset($pages['firstName']);
unset($pages['name']);
unset($pages['company_name']);
unset($pages['email']);
unset($pages['phone']);
arsort($pages);
return $this->render('user/analytics.html.twig', [
'name' => $name,
'pages' => $pages,
'current_page' => 'stats'
]);
}
/**
*@Route("/analytics-user/", name="user.analytics_user")
*/
public function analytics_user(Request $request, UserRepository $userRepository)
{
$page = $request->query->get('page');
$users = $userRepository->getStatsInfo();
$defaultMonth = $request->request->get('periodeSelect') ?? 'all';
extract($this->getStats($users, $defaultMonth));
return $this->render('user/analytics-user.html.twig', [
'users_stats' => $users_stats,
'all_mois' => $all_mois,
'defaultMonth' => $defaultMonth,
'page' => $page,
'current_page' => 'stats'
]);
}
private function getStats($users, $defaultMonth)
{
$users_stats = [];
$all_mois = [];
$i = 0;
foreach ($users as $user) {
if (array_key_exists('mois', $user['dashboard_info'])) {
foreach ($user['dashboard_info']['mois'] as $mois => $value) {
$all_mois[$mois] = 1;
if ($mois != $defaultMonth && $defaultMonth != 'all') {
continue;
}
$value['firstName'] = $user['firstName'];
$value['name'] = $user['name'];
$value['company_name'] = $user['company_name'];
$value['email'] = $user['email'];
$value['phone'] = $user['phone'];
if ($defaultMonth == 'all') {
$sums = array();
if (array_key_exists($i, $users_stats)) {
foreach (array_keys($users_stats[$i] + $value) as $key) {
$sums[$key] = @(intval($users_stats[$i][$key]) + intval($value[$key]));
}
$sums['firstName'] = $user['firstName'];
$sums['name'] = $user['name'];
$sums['company_name'] = $user['company_name'];
$sums['email'] = $user['email'];
$sums['phone'] = $user['phone'];
$users_stats[$i] = $sums;
} else {
$users_stats[$i] = $value;
}
} else {
$users_stats[$mois][] = $value;
}
}
}
$i++;
}
return ['users_stats' => $users_stats, 'all_mois' => $all_mois, 'defaultMonth' => $defaultMonth];
}
/**
*@Route("/add", name="user.add")
*/
public function add(Request $request, UserRepository $userRepository)
{
if (!in_array('ROLE_MASTER', $this->getUser()->getRoles())) {
return $this->redirectToRoute('dashboard.index', [], Response::HTTP_SEE_OTHER);
}
$user = new User();
$form = $this->createForm(UserType::class, $user);
$requestData = $request->request->get('user');
if ($requestData != null) {
switch ($requestData['account_type']) {
case 0:
$user->setParentId(0);
$user->setRoles(['ROLE_USER', 'ROLE_SUPER_ADMIN']);
$user->setApiKey(base_convert(hash('sha256', time() . mt_rand()), 16, 36));
break;
case 1:
$user->setParentId($requestData['parent']);
$user->setRoles(['ROLE_USER']);
$user->setApiKey($userRepository->find($requestData['parent'])->getApiKey());
break;
case 2:
$user->setParentId($requestData['parent']);
$user->setRoles(['ROLE_USER', 'ROLE_MANDATAIRE']);
$user->setApiKey(base_convert(hash('sha256', time() . mt_rand()), 16, 36));
break;
}
$user->setDashboardInfo(json_decode(
'{
"rdv": 0,
"mandats": 0,
"ca_genere": 0,
"ca_potentiel": 0,
"ca_previsionnel": 0
}',
true
));
$user->setPlainPassword($this->setPassword())
->setPassword($this->passwordHasher->hashPassword($user, $user->getPlainPassword()));
$password = $user->getPlainPassword();
}
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->em->persist($user);
$this->em->flush();
if ($user->getParentId() == 0) {
$user->setParentId($user->getId());
$this->em->flush($user);
}
$mailling = new Mailling();
$mailling->setSubject('Votre compte Integraal');
$mailling->setMessage('
<h3>Bienvenue sur Integraal</h3>
<p>Voici vos identifiants pour vous connecter à la plateforme : </p>
<p>
Adresse email : ' . $user->getEmail() . '<br>
Mot de passe : ' . $password . '<br>
' . $this->generateUrl('app.login', [], UrlGeneratorInterface::ABSOLUTE_URL) . '
</p>');
$mailling->setEmailFrom('no-reply@integraal.io');
$mailling->setEmailTo($user->getEmail());
$this->maillingNotification->notify($mailling);
return $this->redirectToRoute('user.index', [], Response::HTTP_SEE_OTHER);
}
return $this->render('user/add.html.twig', [
'form' => $form->createView(),
'current_page' => 'user'
]);
}
/**
*@Route("/{id}/edit", name="user.edit", methods={"GET", "POST"})
*/
public function edit(User $user, Request $request)
{
if (!in_array('ROLE_MASTER', $this->getUser()->getRoles())) {
return $this->redirectToRoute('dashboard.index', [], Response::HTTP_SEE_OTHER);
}
$sendNewId = false;
if ($request->request->get('user') != null && $user->getEmail() != $request->request->get('user')['email']) {
$sendNewId = true;
}
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->em->flush($user);
if ($sendNewId) $this->sendNewIdentifiant($user, '<i>Le mot de passe que vous avez défini.</i>');
return $this->redirectToRoute('user.index', [], Response::HTTP_SEE_OTHER);
}
return $this->render('user/add.html.twig', [
'form' => $form->createView(),
'button_label' => 'Editer l\'utilisateur',
'edit' => true,
'current_page' => 'user'
]);
}
/**
*@Route("/{id}/resetpwd", name="user.resetPassword")
*/
public function resetPassword(User $user, Request $request)
{
if ($this->isCsrfTokenValid('reset-password' . $user->getId(), $request->get('_token'))) {
$user->setPlainPassword($this->setPassword())
->setPassword($this->passwordHasher->hashPassword($user, $user->getPlainPassword()));
$password = $user->getPlainPassword();
$this->em->flush($user);
$this->sendNewIdentifiant($user, $password);
}
return $this->redirectToRoute('user.index', [], Response::HTTP_SEE_OTHER);
}
/**
*@Route("/forgotPassword", name="user.forgotPassword", methods={"GET", "POST"})
*/
public function forgotPassword(Request $request, UserRepository $userRepository)
{
if ($request->request->get('email')) {
if ($this->isCsrfTokenValid('reset-pwd', $request->get('_token'))) {
$users = $userRepository->findBy(['email' => $request->request->get('email')]);
if ($users) {
$user = $users[0];
$user->setPlainPassword($this->setPassword())
->setPassword($this->passwordHasher->hashPassword($user, $user->getPlainPassword()));
$password = $user->getPlainPassword();
$this->em->flush($user);
$this->sendNewIdentifiant($user, $password);
return $this->render('user/forgot_finish.html.twig');
}
}
}
// if($request->request)
return $this->render('user/forgot.html.twig');
}
private function sendNewIdentifiant(User $user, string $password)
{
$mailling = new Mailling();
$mailling->setSubject('Vos identifiants Integraal');
$mailling->setMessage('
<h3>Vos identifiant sur Integraal ont changé</h3>
<p>Voici vos nouveaux identifiant pour vous connecter à la plateforme :</p>
<p>
Adresse email : ' . $user->getEmail() . '<br>
Mot de passe : ' . $password . ' <br>
' . $this->generateUrl('app.login', [], UrlGeneratorInterface::ABSOLUTE_URL) . '
</p>');
$mailling->setEmailFrom('no-reply@integraal.io');
$mailling->setEmailTo($user->getEmail());
$this->maillingNotification->notify($mailling);
}
private function setPassword()
{
$comb = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
$pass = array();
$combLen = strlen($comb) - 1;
for ($i = 0; $i < 8; $i++) {
$n = rand(0, $combLen);
$pass[] = $comb[$n];
}
return implode($pass);
}
private function verifyPassword($data)
{
$password = $data['new_password'];
$uppercase = preg_match('@[A-Z]@', $password);
$lowercase = preg_match('@[a-z]@', $password);
$number = preg_match('@[0-9]@', $password);
$specialChars = preg_match('@[^a-z^0-9^A-Z]@', $password);
if (!$uppercase || !$lowercase || !$number || !$specialChars || strlen($password) < 8) {
return ['<div class="col-12 alert alert-warning">Le mot de passe doit comporter au moins 8 caractères et doit inclure au moins une lettre minuscule, une lettre majuscule, un chiffre et un caractère spécial</div>'];
}
return true;
}
/**
*@Route("/settings", name="user.settings")
*/
public function settingsAccount(Request $request)
{
if ($request->query->get('code')) {
return $this->setAgendaSync($request->query->get('code'));
}
$user = $this->getUser();
$calendar = new Calendar($user, $this->em);
$form = $this->createFormBuilder($user)
->add('email', EmailType::class, ['label' => 'Email'])
->add('first_name', TextType::class, ['label' => 'Prénom'])
->add('name', TextType::class, ['label' => 'Nom'])
->add('new_password', PasswordType::class, ['mapped' => false, 'label' => 'Nouveau mot de passe'])
->add('street', TextType::class, ['label' => 'Adresse'])
->add('street_number', IntegerType::class, ['label' => 'N°'])
->add('zipcode', TextType::class, ['label' => 'Code postal'])
->add('city', TextType::class, ['label' => 'Ville'])
->add('phone', TextType::class, ['label' => 'Téléphone'])
->add('company_name', TextType::class, ['label' => 'Nom de société (Nom affiché en émetteur d\'email)'])
->getForm();
// $form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
$requestData = $request->request->get('form');
if ($form->isSubmitted() && $form->isValid()) {
if (strlen($requestData['new_password']) > 0) {
if ($this->verifyPassword($requestData) === true) {
$user->setPlainPassword($requestData['new_password'])
->setPassword($this->passwordHasher->hashPassword($user, $user->getPlainPassword()));
$password = $user->getPlainPassword();
$this->sendNewIdentifiant($user, $password);
} else {
return $this->render('user/settings.html.twig', [
'form' => $form->createView(),
'current_sub_page' => 'account_settings',
'current_page' => 'user',
'error' => $this->verifyPassword($requestData) ?? '',
'syncLink' => $calendar->getAuthLink($this->generateUrl('user.settings', [], UrlGeneratorInterface::ABSOLUTE_URL))
]);
}
$this->em->flush($user);
} else {
$this->em->flush($user);
}
$this->addFlash(
'notice',
'Les changements ont été sauvegardé.'
);
return $this->redirectToRoute('user.settings', [], Response::HTTP_SEE_OTHER);
}
return $this->render('user/settings.html.twig', [
'form' => $form->createView(),
'current_sub_page' => 'account_settings',
'current_page' => 'user',
'error' => $error ?? '',
'syncLink' => $calendar->getAuthLink($this->generateUrl('user.settings', [], UrlGeneratorInterface::ABSOLUTE_URL))
]);
}
private function setAgendaSync($code = '', $reset = false)
{
$user = $this->getUser();
$calendar = new Calendar($this->getUser(), $this->em);
if ($reset) {
$user->setAgendaToken(NULL);
$user->setAgendaRefreshToken(NULL);
$user->setAgendaExpireIn(NULL);
$user->setAgendaProfile(NULL);
$this->em->flush($user);
}
if ($code != '') {
$token = $calendar->getUserToken($this->generateUrl('user.settings', [], UrlGeneratorInterface::ABSOLUTE_URL), $code);
$user->setAgendaToken($token['access']);
$user->setAgendaRefreshToken($token['refresh']);
$user->setAgendaExpireIn(time() + $token['expireIn']);
$user->setAgendaProfile($token['profile']);
$this->em->flush($user);
}
return $this->redirectToRoute('user.settings', [], Response::HTTP_SEE_OTHER);
}
/**
* @Route("/unsync", name="user.settings.unsync", methods={"GET"})
*/
public function unsync(UserRepository $userRepository)
{
return $this->setAgendaSync('', true);
}
/**
* @Route("/change-user", name="user.changeUser", methods={"POST"})
*/
public function changeUser(Request $request, UserRepository $userRepository): Response
{
if ($request->isXmlHttpRequest()) {
if ($request->request->get('PossessUser') == 'all') {
$request->getSession()->set('userPossess', 'all');
} else {
$request->getSession()->set('userPossess', $userRepository->find($request->request->get('PossessUser')));
}
return new JsonResponse([
'redirect' => $request->headers->get('referer')
]);
}
}
/**
* @Route("/delete/{id}", name="user.delete", methods={"POST"})
*/
public function delete(Request $request, User $user, UserRepository $userRepository, NoteRepository $noteRepository): Response
{
$remove_id = $user->getId();
if ($this->isCsrfTokenValid('delete' . $remove_id, $request->request->get('_token'))) {
$parent = $userRepository->findBy(['id' => $user->getParentId()])[0];
$notes = $noteRepository->findBy(['user' => $user->getId()]);
if ($parent == $user) {
$users = $userRepository->getAllAgent($parent->getId());
foreach ($users as $userRelation) {
if ($userRelation != $parent) {
$this->removeUserRelation($userRelation, $userRepository, $noteRepository);
$this->em->remove($userRelation);
}
}
foreach ($user->getTasksActor() as $item) {
$this->em->remove($item);
$this->em->flush();
}
foreach ($user->getTasks() as $item) {
$this->em->remove($item);
$this->em->flush();
}
foreach ($user->getMaillings() as $item) {
$this->em->remove($item);
$this->em->flush();
}
foreach ($user->getMarkers() as $item) {
$this->em->remove($item);
$this->em->flush();
}
foreach ($user->getNotifications() as $item) {
$this->em->remove($item);
$this->em->flush();
}
foreach ($notes as $item) {
$this->em->remove($item);
$this->em->flush();
}
foreach ($user->getLeadsByPossessor() as $item) {
$this->em->remove($item);
$this->em->flush();
}
} else {
$this->removeUserRelation($user, $userRepository, $noteRepository);
}
$this->em->remove($user);
$this->em->flush();
if ($request->isXmlHttpRequest()) {
return new JsonResponse([
'remove' => 'true'
]);
}
}
return $this->redirectToRoute('user.index', [], Response::HTTP_SEE_OTHER);
}
private function removeUserRelation(User $user, UserRepository $userRepository, NoteRepository $noteRepository)
{
$parent = $userRepository->findBy(['id' => $user->getParentId()])[0];
$notes = $noteRepository->findBy(['user' => $user->getId()]);
foreach ($user->getTasksActor() as $item) {
$item->setUser($parent);
$item->setUserAction($parent);
$this->em->flush();
}
foreach ($user->getTasks() as $item) {
$item->setUser($parent);
$item->setUserAction($parent);
$this->em->flush();
}
foreach ($user->getMaillings() as $item) {
$item->setUser($parent);
$this->em->flush();
}
foreach ($user->getMarkers() as $item) {
$item->setUser($parent);
$this->em->flush();
}
foreach ($user->getNotifications() as $item) {
$item->setUser($parent);
$item->setIsSeen(0);
$this->em->flush();
}
foreach ($notes as $item) {
$item->setUser($parent);
$this->em->flush();
}
foreach ($user->getLeads() as $item) {
$item->setUser($parent);
$this->em->flush();
}
}
}