Passed
Push — master ( 527539...f78a4e )
by Gerrit
02:05
created

GenericEntityInvokeController   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 160
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 6
lcom 1
cbo 6
dl 0
loc 160
ccs 56
cts 56
cp 1
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 33 1
A __invoke() 0 12 1
B invokeEntityMethod() 0 58 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 Addiks\SymfonyGenerics\Services\ArgumentCompilerInterface;
17
use Webmozart\Assert\Assert;
18
use InvalidArgumentException;
19
use ReflectionObject;
20
use ReflectionMethod;
21
use Symfony\Component\HttpFoundation\Request;
22
use Symfony\Component\HttpFoundation\Response;
23
use Addiks\SymfonyGenerics\Events\EntityInteractionEvent;
24
25
final class GenericEntityInvokeController
26
{
27
28
    /**
29
     * @var ControllerHelperInterface
30
     */
31
    private $controllerHelper;
32
33
    /**
34
     * @var ArgumentCompilerInterface
35
     */
36
    private $argumentCompiler;
37
38
    /**
39
     * @var string
40
     */
41
    private $entityClass;
42
43
    /**
44
     * @var string
45
     */
46
    private $entityIdKey;
47
48
    /**
49
     * @var string
50
     */
51
    private $methodName;
52
53
    /**
54
     * @var array
55
     */
56
    private $arguments;
57
58
    /**
59
     * @var string|null
60
     */
61
    private $denyAccessAttribute;
62
63
    /**
64
     * @var string
65
     */
66
    private $successMessage;
67
68
    /**
69
     * @var string|null
70
     */
71
    private $redirectRoute;
72
73
    /**
74
     * @var array
75
     */
76
    private $redirectRouteParameters;
77
78 12
    public function __construct(
79
        ControllerHelperInterface $controllerHelper,
80
        ArgumentCompilerInterface $argumentCompiler,
81
        array $options
82
    ) {
83 12
        Assert::null($this->controllerHelper);
84 12
        Assert::keyExists($options, 'entity-class');
85 11
        Assert::keyExists($options, 'method');
86
87 10
        $options = array_merge([
88 10
            'arguments' => [],
89
            'deny-access-attribute' => null,
90
            'success-message' => "Entity method invoked!",
91
            'redirect-route' => null,
92
            'redirect-route-parameters' => [],
93
            'entity-id-key' => 'entityId',
94 10
        ], $options);
95
96 10
        Assert::classExists($options['entity-class']);
97 9
        Assert::methodExists($options['entity-class'], $options['method']);
98 8
        Assert::isArray($options['arguments'], 'Method-arguments must be array!');
99
100 7
        $this->controllerHelper = $controllerHelper;
101 7
        $this->argumentCompiler = $argumentCompiler;
102 7
        $this->entityClass = $options['entity-class'];
103 7
        $this->entityIdKey = $options['entity-id-key'];
104 7
        $this->methodName = $options['method'];
105 7
        $this->arguments = $options['arguments'];
106 7
        $this->denyAccessAttribute = $options['deny-access-attribute'];
107 7
        $this->successMessage = $options['success-message'];
108 7
        $this->redirectRoute = $options['redirect-route'];
109 7
        $this->redirectRouteParameters = $options['redirect-route-parameters'];
110 7
    }
111
112 2
    public function __invoke(): Response
113
    {
114
        /** @var Request $request */
115 2
        $request = $this->controllerHelper->getCurrentRequest();
116
117 2
        Assert::isInstanceOf($request, Request::class, "Cannot use controller outside of request-scope!");
118
119
        /** @var string $entityId */
120 1
        $entityId = $request->get($this->entityIdKey);
121
122 1
        return $this->invokeEntityMethod($request, $entityId);
123
    }
124
125 5
    public function invokeEntityMethod(Request $request, string $entityId): Response
126
    {
127
        /** @var object|null $entity */
128 5
        $entity = $this->controllerHelper->findEntity($this->entityClass, $entityId);
129
130 5
        if (is_null($entity)) {
131 1
            throw new InvalidArgumentException(sprintf(
132 1
                "Entity with id '%s' not found!",
133 1
                $entityId
134
            ));
135
        }
136
137 4
        if (!empty($this->denyAccessAttribute)) {
138 1
            $this->controllerHelper->denyAccessUnlessGranted($this->denyAccessAttribute, $entity);
139
        }
140
141 3
        $reflectionObject = new ReflectionObject($entity);
142
143
        /** @var ReflectionMethod $reflectionMethod */
144 3
        $reflectionMethod = $reflectionObject->getMethod($this->methodName);
145
146
        /** @var array $callArguments */
147 3
        $callArguments = $this->argumentCompiler->buildCallArguments(
148 3
            $reflectionMethod,
149 3
            $this->arguments,
150 3
            $request
151
        );
152
153 3
        $this->controllerHelper->dispatchEvent("symfony_generics.entity_interaction", new EntityInteractionEvent(
154 3
            $this->entityClass,
155 3
            $entityId,
156 3
            $entity,
157 3
            $this->methodName,
158 3
            $callArguments
159
        ));
160
161
        /** @var mixed $result */
162 3
        $result = $reflectionMethod->invokeArgs($entity, $callArguments);
163
164 3
        $this->controllerHelper->flushORM();
165
166
        /** @var Response $response */
167 3
        $response = null;
0 ignored issues
show
Unused Code introduced by
$response is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
168
169 3
        if (is_null($this->redirectRoute)) {
170 2
            $response = new Response($this->successMessage);
171
172
        } else {
173 1
            $response = $this->controllerHelper->redirectToRoute(
174 1
                $this->redirectRoute,
175 1
                $this->argumentCompiler->buildArguments($this->redirectRouteParameters, $request, [
176 1
                    'result' => $result
177
                ])
178
            );
179
        }
180
181 3
        return $response;
182
    }
183
184
}
185