vendor/sylius/sylius/src/Sylius/Bundle/AdminBundle/EventListener/ResourceDeleteSubscriber.php line 40

Open in your IDE?
  1. <?php
  2. /*
  3. * This file is part of the Sylius package.
  4. *
  5. * (c) Paweł Jędrzejewski
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. declare(strict_types=1);
  11. namespace Sylius\Bundle\AdminBundle\EventListener;
  12. use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
  13. use Sylius\Component\Resource\ResourceActions;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. use Symfony\Component\HttpFoundation\RedirectResponse;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
  18. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  19. use Symfony\Component\HttpKernel\Event\ExceptionEvent;
  20. use Symfony\Component\HttpKernel\KernelEvents;
  21. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  22. final class ResourceDeleteSubscriber implements EventSubscriberInterface
  23. {
  24. public function __construct(private UrlGeneratorInterface $router, private SessionInterface $session)
  25. {
  26. }
  27. public static function getSubscribedEvents(): array
  28. {
  29. return [
  30. KernelEvents::EXCEPTION => 'onResourceDelete',
  31. ];
  32. }
  33. public function onResourceDelete(ExceptionEvent $event): void
  34. {
  35. $exception = $event->getThrowable();
  36. if (!$exception instanceof ForeignKeyConstraintViolationException) {
  37. return;
  38. }
  39. if (\method_exists($event, 'isMainRequest')) {
  40. $isMainRequest = $event->isMainRequest();
  41. } else {
  42. $isMainRequest = $event->isMasterRequest();
  43. }
  44. if (!$isMainRequest || 'html' !== $event->getRequest()->getRequestFormat()) {
  45. return;
  46. }
  47. $eventRequest = $event->getRequest();
  48. $requestAttributes = $eventRequest->attributes;
  49. $originalRoute = $requestAttributes->get('_route');
  50. if (!$this->isMethodDelete($eventRequest) ||
  51. !$this->isSyliusRoute($originalRoute) ||
  52. !$this->isAdminSection($requestAttributes->get('_sylius', []))
  53. ) {
  54. return;
  55. }
  56. $resourceName = $this->getResourceNameFromRoute($originalRoute);
  57. if (null === $requestAttributes->get('_controller')) {
  58. return;
  59. }
  60. /** @var FlashBagInterface $flashBag */
  61. $flashBag = $this->session->getBag('flashes');
  62. $flashBag->add('error', [
  63. 'message' => 'sylius.resource.delete_error',
  64. 'parameters' => ['%resource%' => $resourceName],
  65. ]);
  66. $referrer = $eventRequest->headers->get('referer');
  67. if (null !== $referrer) {
  68. $event->setResponse(new RedirectResponse($referrer));
  69. return;
  70. }
  71. $event->setResponse($this->createRedirectResponse($originalRoute, ResourceActions::INDEX));
  72. }
  73. private function getResourceNameFromRoute(string $route): string
  74. {
  75. $route = str_replace('_bulk', '', $route);
  76. $routeArray = explode('_', $route);
  77. $routeArrayWithoutAction = array_slice($routeArray, 0, count($routeArray) - 1);
  78. $routeArrayWithoutPrefixes = array_slice($routeArrayWithoutAction, 2);
  79. return trim(implode(' ', $routeArrayWithoutPrefixes));
  80. }
  81. private function createRedirectResponse(string $originalRoute, string $targetAction): RedirectResponse
  82. {
  83. $redirectRoute = str_replace(ResourceActions::DELETE, $targetAction, $originalRoute);
  84. return new RedirectResponse($this->router->generate($redirectRoute));
  85. }
  86. private function isMethodDelete(Request $request): bool
  87. {
  88. return Request::METHOD_DELETE === $request->getMethod();
  89. }
  90. private function isSyliusRoute(string $route): bool
  91. {
  92. return str_starts_with($route, 'sylius');
  93. }
  94. private function isAdminSection(array $syliusParameters): bool
  95. {
  96. return array_key_exists('section', $syliusParameters) && 'admin' === $syliusParameters['section'];
  97. }
  98. }