src/Listener/CheckBoModulesListener.php line 39

Open in your IDE?
  1. <?php
  2. namespace App\Listener;
  3. use App\Entity\User;
  4. use App\Services\Common\ModuleSettingService;
  5. use Symfony\Component\HttpFoundation\RedirectResponse;
  6. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  7. use Symfony\Component\HttpKernel\KernelInterface;
  8. use Symfony\Component\Routing\RouterInterface;
  9. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  10. class CheckBoModulesListener
  11. {
  12. private RouterInterface $router;
  13. private KernelInterface $kernel;
  14. private TokenStorageInterface $token;
  15. private ModuleSettingService $moduleSettingService;
  16. public function __construct(
  17. RouterInterface $router,
  18. KernelInterface $kernel,
  19. TokenStorageInterface $token,
  20. ModuleSettingService $moduleSettingService
  21. )
  22. {
  23. $this->router = $router;
  24. $this->kernel = $kernel;
  25. $this->token = $token;
  26. $this->moduleSettingService = $moduleSettingService;
  27. }
  28. /**
  29. * @param ResponseEvent $event
  30. *
  31. * @return void
  32. */
  33. public function onKernelResponse( ResponseEvent $event )
  34. {
  35. $request = $event->getRequest();
  36. $currentRoute = $request->get( '_route' );
  37. if ( NULL === $currentRoute ) {
  38. return;
  39. }
  40. $route = $this->router->getRouteCollection()->get( $currentRoute );
  41. if ( $route->getOption( 'global_module' ) === TRUE ) {
  42. return;
  43. }
  44. // INFORMATION IMPORTANTE:
  45. // Le traitement des routes exclues de listener ne se fait plus ici mais
  46. // directement dans la route en ajoutant l'option "global_module" à TRUE
  47. // exemple:
  48. // back_setting_point_point_transaction_type_list:
  49. // path: /back/setting/point/point-transaction-type/list
  50. // controller: App\Controller\Back\Setting\Point\PointTransactionTypeController::list
  51. // methods: GET
  52. // options:
  53. // global_module: true <== ICI ON ACTIVE LA FONCTION
  54. // requirements:
  55. // _locale: '%app_locales%'
  56. if ( strpos( $currentRoute, 'back_' ) === 0 ) {
  57. // Partie qui gère le back
  58. // On récupère le setting MODULE_SETTING
  59. $modules = $this->moduleSettingService->getModuleSetting();
  60. if ( $modules === [] ) {
  61. return;
  62. }
  63. // On vérifie si le module point est activé afin de ne pas bloquer l'accès à la page de configuration des points
  64. if ( isset( $modules[ 'point' ] ) ) {
  65. if ( $route->getOption( 'global_module' ) === 'point' ) {
  66. return;
  67. }
  68. }
  69. $token = $this->token->getToken();
  70. if( null === $token ) {
  71. return;
  72. }
  73. $currentUser = $token->getUser();
  74. $defaultModules = $this->moduleSettingService->getDefaultYamlModuleSetting($currentUser);
  75. // Exemple d'utilisation
  76. $selectedModules = $this->arrayIntersectKey( $defaultModules[ 'items' ], $modules );
  77. $routes = $this->collectRoutes( $selectedModules, $routes );
  78. if ( !in_array( $request->get( '_route' ), $routes, TRUE ) ) {
  79. $token = $this->token->getToken();
  80. /** @var User $currentUser */
  81. $currentUser = $token ? $token->getUser() : NULL;
  82. if ( $currentUser && $this->kernel->getEnvironment() === 'dev' && $currentUser->isDeveloper() ) {
  83. $event->setResponse(
  84. new RedirectResponse(
  85. $this->router->generate( 'back_route_not_in_module', [
  86. 'route' => $request->get( '_route' ),
  87. 'referer' => $_SERVER[ 'HTTP_REFERER' ] ?? '',
  88. ] ),
  89. ),
  90. );
  91. } else {
  92. $event->setResponse( new RedirectResponse( $this->router->generate( 'back_dashboard' ) ) );
  93. }
  94. }
  95. }
  96. // @TODO : Partie qui gère le front
  97. // Il conviendrait de traiter ici la même logique mais pour le front
  98. }
  99. /**
  100. * @param $defaultModules
  101. * @param $currentModules
  102. *
  103. * @return array
  104. */
  105. private function arrayIntersectKey( $defaultModules, $currentModules ): array
  106. {
  107. $result = [];
  108. foreach ( $defaultModules as $key => $value ) {
  109. if ( isset( $currentModules[ $key ] ) ) {
  110. $result[ $key ] = $value;
  111. }
  112. }
  113. foreach ( $result as $key => $value ) {
  114. if ( !empty( $value[ 'subItems' ] ) ) {
  115. foreach ( $value[ 'subItems' ] as $subKey => $subValue ) {
  116. if ( !isset( $currentModules[ $key ][ 'subItems' ][ $subKey ] ) ) {
  117. unset( $result[ $key ][ 'subItems' ][ $subKey ] );
  118. }
  119. }
  120. }
  121. }
  122. return $result;
  123. }
  124. /**
  125. * @param $array
  126. * @param $result
  127. *
  128. * @return array
  129. */
  130. private function collectRoutes( $array, &$result ): array
  131. {
  132. if ( !is_array( $result ) ) {
  133. $result = [];
  134. }
  135. foreach ( $array as $value ) {
  136. if ( is_array( $value ) ) {
  137. if ( isset( $value[ 'route' ] ) ) {
  138. $result[] = $value[ 'route' ];
  139. }
  140. if ( isset( $value[ 'mainRoute' ] ) ) {
  141. $result[] = $value[ 'mainRoute' ];
  142. }
  143. if ( isset( $value[ 'subItems' ] ) && is_array( $value[ 'subItems' ] ) ) {
  144. // Collecter les "includedRoutes" du sous-niveau
  145. foreach ( $value[ 'subItems' ] as $subItem ) {
  146. if ( isset( $subItem[ 'includedRoutes' ] ) && is_array( $subItem[ 'includedRoutes' ] ) ) {
  147. $result = array_merge( $result, $subItem[ 'includedRoutes' ] );
  148. }
  149. }
  150. }
  151. $this->collectRoutes( $value, $result ); // Appel récursif pour explorer les sous-tableaux
  152. }
  153. }
  154. return $result; // Retourne le tableau résultat une fois que la collecte est terminée
  155. }
  156. }