Completed
Push — master ( f9a038...cc9983 )
by Kamil
22:34
created

ResourceDeleteSubscriber::getSubscribedEvents()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 6
rs 9.4285
nc 1
cc 1
eloc 3
nop 0
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Bundle\ResourceBundle\EventListener;
13
14
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
15
use FOS\RestBundle\View\View;
16
use FOS\RestBundle\View\ViewHandlerInterface as RestViewHandlerInterface;
17
use Sylius\Component\Resource\ResourceActions;
18
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
19
use Symfony\Component\HttpFoundation\RedirectResponse;
20
use Symfony\Component\HttpFoundation\Request;
21
use Symfony\Component\HttpFoundation\Session\SessionInterface;
22
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
23
use Symfony\Component\HttpKernel\KernelEvents;
24
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
25
use Symfony\Component\Translation\TranslatorInterface;
26
27
/**
28
 * @author Jan Góralski <[email protected]>
29
 */
30
class ResourceDeleteSubscriber implements EventSubscriberInterface
31
{
32
    /**
33
     * @var UrlGeneratorInterface
34
     */
35
    private $router;
36
37
    /**
38
     * @var SessionInterface
39
     */
40
    private $session;
41
42
    /**
43
     * @var TranslatorInterface
44
     */
45
    private $translator;
46
47
    /**
48
     * @var RestViewHandlerInterface
49
     */
50
    private $viewHandler;
51
52
    /**
53
     * @param UrlGeneratorInterface $router
54
     * @param SessionInterface $session
55
     * @param TranslatorInterface $translator
56
     * @param RestViewHandlerInterface $viewHandler
57
     */
58
    public function __construct(
59
        UrlGeneratorInterface $router,
60
        SessionInterface $session,
61
        TranslatorInterface $translator,
62
        RestViewHandlerInterface $viewHandler
63
    ) {
64
        $this->router = $router;
65
        $this->session = $session;
66
        $this->translator = $translator;
67
        $this->viewHandler = $viewHandler;
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73
    public static function getSubscribedEvents()
74
    {
75
        return [
76
            KernelEvents::EXCEPTION => 'onResourceDelete',
77
        ];
78
    }
79
80
    /**
81
     * @param GetResponseForExceptionEvent $event
82
     */
83
    public function onResourceDelete(GetResponseForExceptionEvent $event)
84
    {
85
        $exception = $event->getException();
86
        if (!$exception instanceof ForeignKeyConstraintViolationException) {
87
            return;
88
        }
89
90
        $requestAttributes = $event->getRequest()->attributes;
91
        $originalRoute = $requestAttributes->get('_route');
92
        $resourceName = $this->getResourceNameFromRoute($originalRoute);
93
94
        if (!$this->isHtmlRequest($event->getRequest())) {
95
            $event->setResponse(
96
                $this->viewHandler->handle(View::create([
97
                    'error' => [
98
                        'code' => $exception->getSQLState(),
99
                        'message' => $this->translator->trans('sylius.resource.delete_error', ['%resource%' => $resourceName], 'flashes'),
100
                    ]
101
                ], 500))
102
            );
103
104
            return;
105
        }
106
107
        if (null === $requestAttributes->get('_controller')) {
108
            return;
109
        }
110
111
        $this->session->getBag('flashes')->add(
112
            'error',
113
            $this->translator->trans('sylius.resource.delete_error', ['%resource%' => $resourceName], 'flashes')
114
        );
115
116
        $referrer = $event->getRequest()->headers->get('referer');
117
118
        if (null !== $referrer) {
119
            $event->setResponse(new RedirectResponse($referrer));
120
121
            return;
122
        }
123
124
        $event->setResponse($this->createRedirectResponse($originalRoute, ResourceActions::INDEX));
125
    }
126
127
    /**
128
     * @param string $route
129
     *
130
     * @return string
131
     */
132
    private function getResourceNameFromRoute($route)
133
    {
134
        $routeArray = explode('_', $route);
135
        $routeArrayWithoutAction = array_slice($routeArray, 0, count($routeArray) - 1);
136
        $routeArrayWithoutPrefixes = array_slice($routeArrayWithoutAction, 2);
137
138
        return trim(implode(' ', $routeArrayWithoutPrefixes));
139
    }
140
141
    /**
142
     * @param string $originalRoute
143
     * @param string $targetAction
144
     * @param array $parameters
145
     *
146
     * @return RedirectResponse
147
     */
148
    private function createRedirectResponse($originalRoute, $targetAction, array $parameters = [])
149
    {
150
        $redirectRoute = str_replace(ResourceActions::DELETE, $targetAction, $originalRoute);
151
152
        return new RedirectResponse($this->router->generate($redirectRoute, $parameters));
153
    }
154
155
    /**
156
     * @param Request $request
157
     *
158
     * @return bool
159
     */
160
    private function isHtmlRequest(Request $request)
161
    {
162
        return 'html' === $request->getRequestFormat();
163
    }
164
}
165