You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
8.1KB

  1. <?php
  2. namespace Lc\SovBundle\Controller\User;
  3. use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
  4. use Doctrine\ORM\EntityManagerInterface;
  5. use EasyCorp\Bundle\EasyAdminBundle\Collection\EntityCollection;
  6. use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
  7. use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
  8. use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
  9. use EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore;
  10. use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
  11. use EasyCorp\Bundle\EasyAdminBundle\Event\AfterCrudActionEvent;
  12. use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeCrudActionEvent;
  13. use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityDeletedEvent;
  14. use EasyCorp\Bundle\EasyAdminBundle\Exception\EntityRemoveException;
  15. use EasyCorp\Bundle\EasyAdminBundle\Exception\ForbiddenActionException;
  16. use EasyCorp\Bundle\EasyAdminBundle\Exception\InsufficientEntityPermissionException;
  17. use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
  18. use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
  19. use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
  20. use EasyCorp\Bundle\EasyAdminBundle\Security\Permission;
  21. use Lc\SovBundle\Container\User\UserContainer;
  22. use Lc\SovBundle\Controller\AbstractAdminController;
  23. use Lc\SovBundle\Definition\ActionDefinition;
  24. use Lc\SovBundle\Definition\ApplicationDefinition;
  25. use Lc\SovBundle\Definition\RolesDefinition;
  26. use Lc\SovBundle\Definition\RolesDefinitionInterface;
  27. use Lc\SovBundle\Doctrine\EntityManager;
  28. use Lc\SovBundle\Doctrine\Extension\BlameableInterface;
  29. use Lc\SovBundle\Factory\User\UserFactory;
  30. use Lc\SovBundle\Form\User\ConfirmDeleteUserFormType;
  31. use Lc\SovBundle\Model\User\UserInterface;
  32. use Lc\SovBundle\Translation\FlashBagTranslator;
  33. use Lc\SovBundle\Translation\TranslatorAdmin;
  34. use Symfony\Component\HttpFoundation\RequestStack;
  35. abstract class UserAdminController extends AbstractAdminController
  36. {
  37. public function buildIndexActions(Actions $actions): void
  38. {
  39. parent::buildIndexActions($actions);
  40. $actions->add(Crud::PAGE_INDEX, $this->getSwitchUserAction());
  41. }
  42. public function getSwitchUserAction(): Action
  43. {
  44. $switchAction = Action::new(
  45. ActionDefinition::SWITCH_USER,
  46. $this->getTranslatorAdmin()->transAction(ActionDefinition::SWITCH_USER),
  47. 'fa fa-fw fa-user-secret'
  48. )
  49. ->linkToCrudAction(ActionDefinition::SWITCH_USER)
  50. ->setLabel($this->getTranslatorAdmin()->transAction(ActionDefinition::SWITCH_USER))
  51. ->setCssClass('in-dropdown text-info action-confirm action_switch');
  52. return $switchAction;
  53. }
  54. public function overrideEntitiesActions(?EntityCollection $entities, string $pageName): void
  55. {
  56. parent::overrideEntitiesActions($entities, $pageName);
  57. foreach ($entities as $entity) {
  58. foreach ($entity->getActions() as $action) {
  59. if ($action->getName() == ActionDefinition::SWITCH_USER) {
  60. $url = $this->generateUrl(
  61. $this->getParameter('lc_sov.homepage_route'),
  62. array('_switch_user' => $entity->getInstance()->getEmail())
  63. );
  64. $action->setLinkUrl($url);
  65. }
  66. }
  67. }
  68. }
  69. public function configureFields(string $pageName): iterable
  70. {
  71. return [
  72. EmailField::new('email'),
  73. TextField::new('lastname'),
  74. TextField::new('firstname'),
  75. ChoiceField::new('roles')
  76. ->allowMultipleChoices()
  77. ->autocomplete()
  78. ->setChoices($this->getUserContainer()->getRoleDefinition()->getRolesList())
  79. ];
  80. }
  81. public function createEntity(string $entityFqcn)
  82. {
  83. return $this->getUserContainer()->getFactory()->create();
  84. }
  85. public function delete(AdminContext $context)
  86. {
  87. $entityManager = $this->getEntityManager();
  88. // Todo envisager un refactor similaire pour toutes les fonctions CRUD
  89. $eaBeforeCrudActionEventDelete = $this->eaBeforeCrudActionEventDelete($context);
  90. if (!is_null($eaBeforeCrudActionEventDelete)) {
  91. return $eaBeforeCrudActionEventDelete;
  92. }
  93. $user = $context->getEntity()->getInstance();
  94. $event = new BeforeEntityDeletedEvent($user);
  95. $this->container->get('event_dispatcher')->dispatch($event);
  96. if ($event->isPropagationStopped()) {
  97. return $event->getResponse();
  98. }
  99. $user = $event->getEntityInstance();
  100. // Creéer formulaire avec un champ confirm
  101. $confirmDeleteUserForm = $this->createForm(ConfirmDeleteUserFormType::class, null, array(
  102. 'action' => $this->getAdminUrlGenerator()->generateUrl()
  103. ));
  104. $confirmDeleteUserForm->handleRequest($context->getRequest());
  105. $entityManager->delete($user);
  106. $warningMessages = $this->getDeleteUserWarningMessageList($user);
  107. //Avant la suppression on s'assure que l'utilisateur à confirmer et qu'il n'y aucun message d'erreur
  108. if ($confirmDeleteUserForm->isSubmitted() && count($warningMessages['danger']) === 0) {
  109. //Détecter les tables qui possède des relations avec un champ qui n'existe plus
  110. //Dans le cas ci-dessous détecter les adresses lié à un utilisateur qui n'existe plus
  111. //SELECT * FROM address a LEFT OUTER JOIN user u ON(u.id=a.user_id) WHERE u.id is null
  112. try {
  113. $entityManager->flush();
  114. $this->addFlashTranslator('success', 'deleted');
  115. } catch (ForeignKeyConstraintViolationException $e) {
  116. throw new EntityRemoveException(['entity_name' => $context->getEntity()->getName(), 'message' => $e->getMessage()]);
  117. }
  118. return $this->redirect($this->getAdminUrlGenerator()->setAction(Crud::PAGE_INDEX)->setEntityId(null)->generateUrl());
  119. }else{
  120. if($confirmDeleteUserForm->isSubmitted()){
  121. $this->addFlashTranslator('error', 'cannotDelete');
  122. }
  123. }
  124. $responseParameters = $this->configureResponseParameters(KeyValueStore::new([
  125. 'pageName' => Crud::PAGE_DETAIL,
  126. 'templatePath' => '@LcSov/adminlte/crud/delete.html.twig',
  127. 'confirm_delete_user_form' => $confirmDeleteUserForm->createView(),
  128. 'global_actions' => array(),
  129. 'batch_actions' => array(),
  130. 'warning_message_list' => $warningMessages
  131. ]));
  132. $event = new AfterCrudActionEvent($context, $responseParameters);
  133. $this->get('event_dispatcher')->dispatch($event);
  134. if ($event->isPropagationStopped()) {
  135. return $event->getResponse();
  136. }
  137. return $responseParameters;
  138. }
  139. public function getDeleteUserWarningMessageList(UserInterface $user): array
  140. {
  141. $warningMessages = array();
  142. $warningMessages['danger'] = [];
  143. $warningMessages['warning'] = [];
  144. $warningMessages['info'] = [];
  145. $entityManager = $this->getEntityManager();
  146. $entityToDeleteListCount = array();
  147. $entityToDeleteListName = array();
  148. foreach ($entityManager->getUnitOfWork()->getScheduledEntityDeletions() as $entityToDelete) {
  149. if (isset($entityToDeleteListCount[(new \ReflectionClass($entityToDelete))->getShortName()])) {
  150. $entityToDeleteListCount[(new \ReflectionClass($entityToDelete))->getShortName()]++;
  151. } else {
  152. $entityToDeleteListCount[(new \ReflectionClass($entityToDelete))->getShortName()] = 1;
  153. }
  154. $entityToDeleteListName[(new \ReflectionClass($entityToDelete))->getShortName()][] = $entityToDelete->getId();
  155. }
  156. foreach ($entityToDeleteListCount as $entityName => $entityToDeleteCount) {
  157. $warningMessages['info'][] = $this->getTranslatorAdmin()->transFlashMessage(
  158. 'error',
  159. 'deleteEntityCascade',
  160. 'User',
  161. array(
  162. '%entity%' => $this->getTranslatorAdmin()->trans('entity.'.$entityName.'.label_plurial'),
  163. '%count%' => $entityToDeleteCount
  164. )
  165. );
  166. }
  167. return $warningMessages;
  168. }
  169. }