src/Factory/Security/SecurityFormFactory.php line 97

Open in your IDE?
  1. <?php
  2. namespace App\Factory\Security;
  3. use App\Entity\Interfaces\SpotHitCampaignInterface;
  4. use App\Entity\Regate;
  5. use App\Entity\RequestRegistration;
  6. use App\Entity\SmsSpotHitCampaign;
  7. use App\Entity\User;
  8. use App\Factory\Platform\MailerFactory;
  9. use App\Services\Common\Email\MailTypes;
  10. use App\Services\Common\MailerService;
  11. use App\Services\Common\Sms\SmsTypes;
  12. use App\Services\Common\User\WorkflowUser;
  13. use App\Services\ConfigService;
  14. use App\Services\DTV\YamlConfig\YamlReader;
  15. use App\Services\Portal\PortalService;
  16. use App\Services\Security\RegisterService;
  17. use App\Services\SpotHitService;
  18. use Doctrine\ORM\EntityManagerInterface;
  19. use Exception;
  20. use RuntimeException;
  21. use Symfony\Component\Form\FormFactoryInterface;
  22. use Symfony\Component\Form\FormInterface;
  23. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  24. use Symfony\Component\Translation\TranslatableMessage;
  25. use Symfony\Component\Validator\Validator\ValidatorInterface;
  26. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  27. use Twig\Error\LoaderError;
  28. use Twig\Error\RuntimeError;
  29. use Twig\Error\SyntaxError;
  30. class SecurityFormFactory
  31. {
  32. private string $domain;
  33. private FormFactoryInterface $formFactory;
  34. private UserPasswordHasherInterface $userPasswordHasher;
  35. private EntityManagerInterface $em;
  36. private ValidatorInterface $validator;
  37. private MailerService $mailerService;
  38. private YamlReader $yamlReader;
  39. private WorkflowUser $workflowUser;
  40. private RegisterService $registerService;
  41. private PortalService $portalService;
  42. private SpotHitService $spotHitService;
  43. public function __construct(
  44. ConfigService $configService,
  45. FormFactoryInterface $formFactory,
  46. UserPasswordHasherInterface $userPasswordHasher,
  47. EntityManagerInterface $em,
  48. ValidatorInterface $validator,
  49. YamlReader $yamlReader,
  50. MailerService $mailerService,
  51. WorkflowUser $workflowUser,
  52. RegisterService $registerService,
  53. PortalService $portalService,
  54. SpotHitService $spotHitService
  55. ) {
  56. $this->domain = $configService->get('subdomain');
  57. $this->formFactory = $formFactory;
  58. $this->userPasswordHasher = $userPasswordHasher;
  59. $this->em = $em;
  60. $this->validator = $validator;
  61. $this->yamlReader = $yamlReader;
  62. $this->mailerService = $mailerService;
  63. $this->workflowUser = $workflowUser;
  64. $this->registerService = $registerService;
  65. $this->portalService = $portalService;
  66. $this->spotHitService = $spotHitService;
  67. }
  68. private function getGlobalRegisterConfig(): array
  69. {
  70. return $this->yamlReader->getRegister();
  71. }
  72. /**
  73. * Retourne le formulaire d'inscription selon le projet
  74. *
  75. * @param User $user
  76. *
  77. * @return FormInterface
  78. *
  79. * @throws Exception
  80. */
  81. public function generateRegisterForm(User $user): FormInterface
  82. {
  83. // on regarde si le register est actif sur la partie login de security ou s'il est actif sur une page à part
  84. if ($this->isRegisterEnabled()) {
  85. $formType = 'App\Form\Type\Registration\\' . $this->getGlobalRegisterConfig()[ 'type' ];
  86. return $this->formFactory->create($formType, $user);
  87. }
  88. throw new RuntimeException('impossible de trouver le projet pour la génération du formulaire d\'inscription, projet : ' . $this->domain);
  89. }
  90. /**
  91. * @return bool|mixed
  92. */
  93. public function isRegisterEnabled()
  94. {
  95. $globalEnabled = $this->getGlobalRegisterConfig()[ 'enabled' ];
  96. $isEnabled = $globalEnabled;
  97. // $frontConfig = $this->yamlReader->getFrontSecurity();
  98. // $loginEnabled = $frontConfig[ 'login' ][ 'sections' ][ 'section_register' ][ 'enabled' ];
  99. // $registerEnabled = $frontConfig[ 'register' ][ 'enabled' ];
  100. // if ($isEnabled) {
  101. // $isEnabled = $loginEnabled !== $registerEnabled;
  102. // }
  103. return $isEnabled;
  104. }
  105. /**
  106. * Fait le post traitement du formulaire d'inscription selon le projet
  107. *
  108. * @param FormInterface $form
  109. * @param User $user
  110. *
  111. * @return array
  112. *
  113. * @throws LoaderError
  114. * @throws RuntimeError
  115. * @throws SyntaxError
  116. * @throws Exception|TransportExceptionInterface
  117. */
  118. public function postProcessingRegisterForm(FormInterface $form, User $user): array
  119. {
  120. $globalRegisterConfig = $this->getGlobalRegisterConfig();
  121. // Registration pour les plateformes qui n'ont pas de mot de passe à renseigner lors de l'inscription
  122. if ($form->has('password')) {
  123. $plainPassword = $form->get('password')->getData();
  124. $user->setPassword($this->userPasswordHasher->hashPassword($user, $plainPassword));
  125. } else {
  126. $user->setPassword('pending-validation');
  127. }
  128. // TODO changer si besoin de personnalisation
  129. $email_validate = $globalRegisterConfig[ 'email_validate' ];
  130. $emails = [];
  131. if (!in_array($email_validate, [NULL, ''], TRUE)) {
  132. $email_validate = str_replace(' ', '', $email_validate);
  133. $emails = explode(';', $email_validate);
  134. } else {
  135. $emails[] = 'dev@37deux.com';
  136. }
  137. $contactRegisterValidate = [];
  138. foreach ($emails as $email) {
  139. if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
  140. $contactRegisterValidate[] = [
  141. "name" => $email,
  142. "email" => $email,
  143. ];
  144. }
  145. }
  146. switch ($globalRegisterConfig[ 'process' ]) {
  147. case 'register_validate': // challenge-eastim-peugeotfi.dtv.loc & citroentf
  148. ///check doublon email en BDD
  149. $userDoublon = $this->em->getRepository(User::class)->findOneBy(['email' => $form->get('email')->getData()]);
  150. if($userDoublon && $userDoublon->getId() !== $form->getData()->getId()) {
  151. $result = [
  152. 'type' => 'danger',
  153. 'route' => 'app_login',
  154. 'message' => new TranslatableMessage('cette email existe déjà'),
  155. ];
  156. break;
  157. }
  158. $user->setRoles(['ROLE_USER']);
  159. $this->em->persist($user);
  160. $requestRegistration = new RequestRegistration();
  161. $requestRegistration->setUser($user);
  162. $this->em->persist($requestRegistration);
  163. $this->em->flush();
  164. $this->workflowUser->needAdminValidation($user);
  165. // Mail validation inscription
  166. $this->mailerService->createApiMailRequest(MailTypes::REGISTRATION_TO_VALIDATE);
  167. foreach ($contactRegisterValidate as $item) {
  168. $this->mailerService->addRecipientToRequest(
  169. [
  170. 'name' => $item[ 'name' ],
  171. 'email' => $item[ 'email' ],
  172. ],
  173. MailerFactory::buildRegistrationToValidate($user)
  174. );
  175. }
  176. $this->mailerService->send();
  177. $result = [
  178. 'type' => 'success',
  179. 'route' => 'app_login',
  180. 'message' => new TranslatableMessage('votre inscription a été envoyée'),
  181. ];
  182. break;
  183. case 'register_regate_job': // animation-lpm
  184. $job = $form->get('job')->getData();
  185. $regateCode = $form->get('regate')->getData();
  186. $regate = $this->em->getRepository(Regate::class)
  187. ->findOneBy(['affectation' => $regateCode,])
  188. ;
  189. $user->setRoles(['ROLE_USER'])
  190. ->setJob($job)
  191. ->setRegate($regate)
  192. ;
  193. $this->em->persist($user);
  194. $requestRegistration = new RequestRegistration();
  195. $requestRegistration->setUser($user);
  196. $this->em->persist($requestRegistration);
  197. $this->em->flush();
  198. $this->workflowUser->needAdminValidation($user);
  199. // Mail validation inscription
  200. $this->mailerService->createApiMailRequest(MailTypes::REGISTRATION_TO_VALIDATE);
  201. foreach ($contactRegisterValidate as $item) {
  202. $this->mailerService->addRecipientToRequest(
  203. [
  204. 'name' => $item[ 'name' ],
  205. 'email' => $item[ 'email' ],
  206. ],
  207. MailerFactory::buildRegistrationToValidate($user)
  208. );
  209. }
  210. $this->mailerService->send();
  211. $result = [
  212. 'type' => 'success',
  213. 'route' => 'app_login',
  214. 'message' => new TranslatableMessage('votre inscription a été envoyée'),
  215. ];
  216. break;
  217. case 'register_validate_zipcode_commercial': // Rehau
  218. $user->setRoles(['ROLE_USER'])->setJob('installer');
  219. ///check doublon email en BDD
  220. $userDoublon = $this->em->getRepository(User::class)->findOneBy(['email' => $form->get('email')->getData()]);
  221. if($userDoublon && $userDoublon->getId() !== $form->getData()->getId()) {
  222. $result = [
  223. 'type' => 'danger',
  224. 'route' => 'app_register',
  225. 'message' => new TranslatableMessage('cette email existe déjà'),
  226. ];
  227. break;
  228. }
  229. // Validation par un commercial
  230. $linkedCommercial = NULL;
  231. if (!isset($globalRegisterConfig[ 'validation_by_commercial' ]) || $globalRegisterConfig[ 'validation_by_commercial' ] === TRUE)
  232. {
  233. $linkedCommercials = $this->em->getRepository(User::class)->findCommercialByDepartment(substr($user->getPostcode(), 0, 2));
  234. if (count($linkedCommercials) > 0) {
  235. /** @var User $linkedCommercial */
  236. $linkedCommercial = $linkedCommercials[ 0 ];
  237. $user->setCommercial($linkedCommercial);
  238. } else {
  239. $result = [
  240. 'type' => 'danger',
  241. 'route' => 'app_register',
  242. 'message' => new TranslatableMessage('impossible de trouver un commercial dans votre département'),
  243. ];
  244. break;
  245. }
  246. }
  247. $this->em->persist($user);
  248. $requestRegistration = new RequestRegistration();
  249. $requestRegistration->setUser($user)->setReferent($linkedCommercial);
  250. $this->em->persist($requestRegistration);
  251. // Mail de validation par un commercial
  252. if ((!isset($globalRegisterConfig[ 'validation_by_commercial' ]) || $globalRegisterConfig[ 'validation_by_commercial' ] === TRUE) && $linkedCommercial instanceof User)
  253. {
  254. $validateurs = [$linkedCommercial];
  255. if(!empty($globalRegisterConfig[ 'validation_by_admin']))
  256. {
  257. $admins = !is_array($globalRegisterConfig['validation_by_admin']) ? [$globalRegisterConfig['validation_by_admin']] : $globalRegisterConfig['validation_by_admin'];
  258. foreach($admins as $admin)
  259. {
  260. $admin = $this->em->getRepository(User::class)->createQueryBuilder('u')
  261. ->where('u.roles LIKE \'%ROLE_ADMIN%\'')
  262. ->andWhere('u.status IN (\'cgu_pending\', \'enabled\')')
  263. ->andWhere('u.email = :email')->setParameter('email', $admin)
  264. ->setMaxResults(1)
  265. ->getQuery()->getOneOrNullResult()
  266. ;
  267. if($admin) $validateurs[] = $admin;
  268. }
  269. }
  270. foreach($validateurs as $validateur)
  271. {
  272. $this->mailerService
  273. ->createApiMailRequest(MailTypes::REGISTRATION_TO_VALIDATE)
  274. ->addRecipientToRequest($validateur, MailerFactory::buildRegistrationToValidate($user))
  275. ->send()
  276. ;
  277. }
  278. }
  279. $this->workflowUser->needAdminValidation($user);
  280. $this->em->flush();
  281. $result = [
  282. 'type' => 'success',
  283. 'route' => 'app_register_waiting_validation',
  284. 'message' => new TranslatableMessage('votre inscription a été envoyée'),
  285. ];
  286. break;
  287. case 'register_replace_fake_user_by_sellerCode':
  288. $user = $this->registerService->registerReplaceFakeUserBySellerCode(
  289. $user,
  290. $form->get('sellerCode')->getData()
  291. );
  292. $result = $this->handleUserResult($user);
  293. break;
  294. case 'register_replace_fake_user_with_accountId_by_sellerCode':
  295. $user = $this->registerService->registerReplaceAccountIdFakeUserBySellerCodeOrAccountId(
  296. $user,
  297. $form,
  298. false,
  299. 'sellerCode'
  300. );
  301. $result = $this->handleUserResult($user);
  302. break;
  303. case 'register_replace_fake_user_with_accountId_by_accountId':
  304. $user = $this->registerService->registerReplaceAccountIdFakeUserBySellerCodeOrAccountId(
  305. $user,
  306. $form,
  307. false,
  308. 'accountId'
  309. );
  310. $result = $this->handleUserResult($user);
  311. break;
  312. default:
  313. throw new RuntimeException(
  314. 'impossible de trouver le process pour post-traiter le formulaire d\'inscription. process : ' . $globalRegisterConfig[ 'process' ],
  315. );
  316. }
  317. if($user instanceof User && $result['type'] === 'success' && $form->has('sendCguBySms') && $form->get('sendCguBySms')->getData())
  318. {
  319. $smsCampaign = $this->spotHitService->createSmsCampaign(
  320. SmsSpotHitCampaign::CAMPAIGN_TYPE_ACCEPT_CGU_FIRST,
  321. $this->yamlReader->getMailer()['transactional_sms'][SmsTypes::ACCEPT_CGU_FIRST],
  322. $user,
  323. 'SMS_' . SmsTypes::ACCEPT_CGU_FIRST . '_' . $user->getId() . '_' . (new \DateTime())->format('YmdHis')
  324. );
  325. $smsCampaign->setStatut(SpotHitCampaignInterface::STATUT_EN_COURS);
  326. $this->em->flush();
  327. $return = $this->spotHitService->sendSmsCampaign($smsCampaign);
  328. if(is_string($return)) {
  329. $smsCampaign->setStatut(SpotHitCampaignInterface::STATUT_EN_ERREUR);
  330. $smsCampaign->setErreur($return);
  331. $result = [
  332. 'type' => 'danger',
  333. 'route' => 'app_register',
  334. 'message' => new TranslatableMessage("une erreur est survenue lors de l'envoi du sms"),
  335. ];
  336. }
  337. else {
  338. $smsCampaign->setStatut(SpotHitCampaignInterface::STATUT_ENVOYEE);
  339. $result = [
  340. 'type' => 'success',
  341. 'route' => 'app_register',
  342. 'message' => new TranslatableMessage("vous allez recevoir un email ainsi qu'un sms pour confirmer votre inscription"),
  343. ];
  344. }
  345. $this->em->flush();
  346. }
  347. return $result;
  348. }
  349. private function handleUserResult($result): array
  350. {
  351. if ($result instanceof User) {
  352. return [
  353. 'type' => 'success',
  354. 'route' => 'app_login',
  355. 'message' => new TranslatableMessage('vous allez recevoir un email pour confirmer votre inscription'),
  356. ];
  357. }
  358. return [
  359. 'type' => 'danger',
  360. 'route' => 'app_login',
  361. 'message' => new TranslatableMessage("une erreur s'est produite, veuillez réessayer"),
  362. ];
  363. }
  364. /**
  365. * @param FormInterface $form
  366. *
  367. * @return FormInterface
  368. *
  369. * @throws Exception
  370. */
  371. public function postValidateRegisterForm(FormInterface $form): FormInterface
  372. {
  373. return $this->registerService->postValidateForm($this->getGlobalRegisterConfig()[ 'post_validate' ], $form);
  374. }
  375. }