Passed
Push — master ( d0187e...7d6d5a )
by Gerrit
62:29
created

GenericServiceInvokeController   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 87.8%

Importance

Changes 0
Metric Value
wmc 5
lcom 1
cbo 5
dl 0
loc 130
ccs 36
cts 41
cp 0.878
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 29 1
A callService() 0 45 4
1
<?php
2
/**
3
 * Copyright (C) 2018 Gerrit Addiks.
4
 * This package (including this file) was released under the terms of the GPL-3.0.
5
 * You should have received a copy of the GNU General Public License along with this program.
6
 * If not, see <http://www.gnu.org/licenses/> or send me a mail so i can send you a copy.
7
 *
8
 * @license GPL-3.0
9
 *
10
 * @author Gerrit Addiks <[email protected]>
11
 */
12
13
namespace Addiks\SymfonyGenerics\Controllers\API;
14
15
use Addiks\SymfonyGenerics\Controllers\ControllerHelperInterface;
16
use Webmozart\Assert\Assert;
17
use Psr\Container\ContainerInterface;
18
use Addiks\SymfonyGenerics\Services\ArgumentCompilerInterface;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\HttpFoundation\Request;
21
use ErrorException;
22
use ReflectionObject;
23
use ReflectionMethod;
24
25
final class GenericServiceInvokeController
26
{
27
28
    /**
29
     * @var ControllerHelperInterface
30
     */
31
    private $controllerHelper;
32
33
    /**
34
     * @var ArgumentCompilerInterface
35
     */
36
    private $argumentCompiler;
37
38
    /**
39
     * @var ContainerInterface
40
     */
41
    private $container;
42
43
    /**
44
     * @var string
45
     */
46
    private $serviceId;
47
48
    /**
49
     * @var string
50
     */
51
    private $method;
52
53
    /**
54
     * @var array
55
     */
56
    private $arguments;
57
58
    /**
59
     * @var string|null
60
     */
61
    private $authorizationAttribute;
62
63
    /**
64
     * @var string|null
65
     */
66
    private $successRedirectRoute;
67
68
    /**
69
     * @var array
70
     */
71
    private $successRedirectArguments;
72
73
    /**
74
     * @var integer
75
     */
76
    private $successRedirectStatus;
77
78 6
    public function __construct(
79
        ControllerHelperInterface $controllerHelper,
80
        ArgumentCompilerInterface $argumentCompiler,
81
        ContainerInterface $container,
82
        array $options
83
    ) {
84 6
        Assert::null($this->controllerHelper);
85 6
        Assert::keyExists($options, 'service');
86 5
        Assert::keyExists($options, 'method');
87
88 4
        $options = array_merge([
89 4
            'arguments' => [],
90
            'authorization-attributes' => null,
91
            'success-redirect' => null,
92
            'success-redirect-arguments' => [],
93
            'success-redirect-status' => 303,
94 4
        ], $options);
95
96 4
        $this->controllerHelper = $controllerHelper;
97 4
        $this->argumentCompiler = $argumentCompiler;
98 4
        $this->container = $container;
99 4
        $this->serviceId = $options['service'];
100 4
        $this->method = $options['method'];
101 4
        $this->arguments = $options['arguments'];
102 4
        $this->authorizationAttribute = $options['authorization-attributes'];
103 4
        $this->successRedirectRoute = $options['success-redirect'];
104 4
        $this->successRedirectArguments = $options['success-redirect-arguments'];
105 4
        $this->successRedirectStatus = (int)$options['success-redirect-status'];
106 4
    }
107
108 3
    public function callService(Request $request): Response
109
    {
110 3
        if (!is_null($this->authorizationAttribute)) {
111 1
            $this->controllerHelper->denyAccessUnlessGranted($this->authorizationAttribute, $request);
112
        }
113
114
        /** @var object|null $service */
115 2
        $service = $this->container->get($this->serviceId);
116
117 2
        if (is_null($service)) {
118 1
            throw new ErrorException(sprintf(
119 1
                "Could not find service '%s'!",
120 1
                $this->serviceId
121
            ));
122
        }
123
124 1
        $reflectionObject = new ReflectionObject($service);
125
126
        /** @var ReflectionMethod $reflectionMethod */
127 1
        $reflectionMethod = $reflectionObject->getMethod($this->method);
128
129
        /** @var array $arguments */
130 1
        $arguments = $this->argumentCompiler->buildCallArguments(
131 1
            $reflectionMethod,
132 1
            $this->arguments,
133 1
            $request
134
        );
135
136 1
        $reflectionMethod->invokeArgs($service, $arguments);
137
138 1
        $this->controllerHelper->flushORM();
139
140 1
        if (!empty($this->successRedirectRoute)) {
141
            /** @var array $redirectArguments */
142
            $redirectArguments = $this->argumentCompiler->buildArguments($this->successRedirectArguments, $request);
143
144
            return $this->controllerHelper->redirectToRoute(
145
                $this->successRedirectRoute,
146
                $redirectArguments,
147
                $this->successRedirectStatus
148
            );
149
        }
150
151 1
        return new Response("Service call completed");
152
    }
153
154
}
155