Completed
Pull Request — master (#311)
by Łukasz
05:40
created

AbstractFormValidRequestHandler   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 10
dl 0
loc 84
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A handleRequest() 0 21 4
A isValidPostRequest() 0 4 2
A getRedirectResponse() 0 15 2
action() 0 1 ?
getPreSaveEventName() 0 1 ?
getPostSaveEventName() 0 1 ?
A validateEvent() 0 10 2
A validateElement() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * (c) FSi sp. z o.o. <[email protected]>
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 FSi\Bundle\AdminBundle\Admin\Context\Request;
13
14
use FSi\Bundle\AdminBundle\Admin\Element;
15
use FSi\Bundle\AdminBundle\Admin\RedirectableElement;
16
use FSi\Bundle\AdminBundle\Event\AdminEvent;
17
use FSi\Bundle\AdminBundle\Event\FormEvent;
18
use FSi\Bundle\AdminBundle\Exception\RequestHandlerException;
19
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
20
use Symfony\Component\HttpFoundation\RedirectResponse;
21
use Symfony\Component\HttpFoundation\Request;
22
use Symfony\Component\HttpFoundation\Response;
23
use Symfony\Component\Routing\RouterInterface;
24
25
abstract class AbstractFormValidRequestHandler extends AbstractHandler
26
{
27
    /**
28
     * @var RouterInterface
29
     */
30
    protected $router;
31
32
    public function __construct(
33
        EventDispatcherInterface $eventDispatcher,
34
        RouterInterface $router
35
    ) {
36
        parent::__construct($eventDispatcher);
37
        $this->router = $router;
38
    }
39
40
    public function handleRequest(AdminEvent $event, Request $request): ?Response
41
    {
42
        $event = $this->validateEvent($event);
43
        if (!$this->isValidPostRequest($event, $request)) {
44
            return null;
45
        }
46
47
        $this->eventDispatcher->dispatch($this->getPreSaveEventName(), $event);
48
        if ($event->hasResponse()) {
49
            return $event->getResponse();
50
        }
51
52
        $this->action($event, $request);
53
54
        $this->eventDispatcher->dispatch($this->getPostSaveEventName(), $event);
55
        if ($event->hasResponse()) {
56
            return $event->getResponse();
57
        }
58
59
        return $this->getRedirectResponse($event, $request);
60
    }
61
62
    protected function isValidPostRequest(FormEvent $event, Request $request): bool
63
    {
64
        return $request->isMethod('POST') && $event->getForm()->isValid();
65
    }
66
67
    protected function getRedirectResponse(FormEvent $event, Request $request): RedirectResponse
68
    {
69
        if ($request->query->has('redirect_uri')) {
70
            return new RedirectResponse($request->query->get('redirect_uri'));
71
        }
72
73
        $element = $this->validateElement($event->getElement());
74
75
        return new RedirectResponse(
76
            $this->router->generate(
77
                $element->getSuccessRoute(),
78
                $element->getSuccessRouteParameters()
79
            )
80
        );
81
    }
82
83
    abstract protected function action(FormEvent $event, Request $request): void;
84
85
    abstract protected function getPreSaveEventName(): string;
86
87
    abstract protected function getPostSaveEventName(): string;
88
89
    private function validateEvent(AdminEvent $event): FormEvent
90
    {
91
        if (!$event instanceof FormEvent) {
92
            throw new RequestHandlerException(sprintf('%s requires FormEvent', get_class($this)));
93
        }
94
95
        $this->validateElement($event->getElement());
96
97
        return $event;
98
    }
99
100
    private function validateElement(Element $element): RedirectableElement
101
    {
102
        if (!$element instanceof RedirectableElement) {
103
            throw new RequestHandlerException(sprintf('%s requires RedirectableElement', get_class($this)));
104
        }
105
106
        return $element;
107
    }
108
}
109