Test Setup Failed
Push — master ( e2ccdd...da0315 )
by Gerrit
09:14
created

GenericEntityFetchController   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 144
Duplicated Lines 38.19 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 98%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 9
dl 55
loc 144
ccs 49
cts 50
cp 0.98
rs 10
c 0
b 0
f 0

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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 InvalidArgumentException;
17
use Webmozart\Assert\Assert;
18
use Symfony\Component\HttpFoundation\Response;
19
use Symfony\Component\Serializer\Encoder\EncoderInterface;
20
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
21
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
22
use ErrorException;
23
use Addiks\SymfonyGenerics\Controllers\ApplyDataTemplateTrait;
24
use Addiks\SymfonyGenerics\Events\EntityInteractionEvent;
25
use Symfony\Component\HttpFoundation\Request;
26
27
final class GenericEntityFetchController
28
{
29
    use ApplyDataTemplateTrait;
30
31
    /**
32
     * @var ControllerHelperInterface
33
     */
34
    private ControllerHelperInterface $controllerHelper;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
35
36
    private ?EncoderInterface $encoder;
37
38
    private ?NormalizerInterface $normalizer;
39
40
    private ?array $dataTemplate;
41
42
    private ?string $authorizationAttribute;
43
44
    /** @var class-string */
45
    private string $entityClass;
46
47
    private string $entityIdKey;
48
49
    private string $format;
50
51
    public function __construct(
52
        ControllerHelperInterface $controllerHelper,
53
        array $options
54
    ) {
55
        Assert::keyExists($options, 'entity-class');
56
57
        $options = array_merge([
58
            'format' => 'json',
59
            'encoder' => null,
60
            'normalizer' => null,
61
            'data-template' => null,
62
            'authorization-attribute' => null,
63
            'entity-id-key' => 'entityId',
64
        ], $options);
65
66
        Assert::true(is_null($options['encoder']) || $options['encoder'] instanceof EncoderInterface);
67
        Assert::true(is_null($options['normalizer']) || $options['normalizer'] instanceof NormalizerInterface);
68
        Assert::classExists($options['entity-class']);
69
70
        $this->controllerHelper = $controllerHelper;
71 13
        $this->entityIdKey = $options['entity-id-key'];
72
        $this->encoder = $options['encoder'];
73
        $this->normalizer = $options['normalizer'];
74
        $this->entityClass = $options['entity-class'];
75 13
        $this->format = $options['format'];
76 13
        $this->dataTemplate = $options['data-template'];
77
        $this->authorizationAttribute = $options['authorization-attribute'];
78 12
    }
79 12
80
    public function __invoke(): Response
81
    {
82
        /** @var Request $request */
83
        $request = $this->controllerHelper->getCurrentRequest();
84
85 12
        Assert::isInstanceOf($request, Request::class, "Cannot use controller outside of request-scope!");
86
87 12
        /** @var string $entityId */
88 11
        $entityId = $request->get($this->entityIdKey);
89 10
90
        return $this->fetchEntity($entityId);
91 9
    }
92 9
93 9
    public function fetchEntity(string $entityId): Response
94 9
    {
95 9
        /** @var object $entity */
96 9
        $entity = $this->controllerHelper->findEntity($this->entityClass, $entityId);
97 9
98 9
        if (is_null($entity)) {
99 9
            throw new InvalidArgumentException(sprintf(
100
                "Could not find entity with id '%s'!",
101 2
                $entityId
102
            ));
103
        }
104 2
105
        if (!empty($this->authorizationAttribute)) {
106 2
            $this->controllerHelper->denyAccessUnlessGranted($this->authorizationAttribute, $entity);
107
        }
108
109 1
        $this->controllerHelper->dispatchEvent("symfony_generics.entity_interaction", new EntityInteractionEvent(
110
            $this->entityClass,
111 1
            $entityId,
112
            $entity,
113
            "*FETCH*"
114 7
        ));
115
116
        /** @var array $normalizedEntity */
117 7
        $normalizedEntity = array();
118
119 7
        if ($this->normalizer instanceof NormalizerInterface) {
120 1
            $normalizedEntity = $this->normalizer->normalize($entity);
121 1
122 1
        } else {
123
            $normalizer = new ObjectNormalizer();
124
125
            $normalizedEntity = $normalizer->normalize($entity);
126 6
        }
127 1
128
        if (!is_array($normalizedEntity)) {
129
            throw new ErrorException("Result of normalize process must be an array!");
130 5
        }
131 5
132 5
        if (!is_null($this->dataTemplate)) {
133 5
            $normalizedEntity = $this->applyDataTemplate($normalizedEntity, $this->dataTemplate);
134 5
        }
135
136
        /** @var string $serializedEntity */
137
        $serializedEntity = "";
138 5
139
        if ($this->encoder instanceof EncoderInterface) {
140 5
            $serializedEntity = $this->encoder->encode($normalizedEntity, $this->format);
141 1
142
        } else {
143
            $serializedEntity = json_encode($normalizedEntity);
144 4
        }
145
146 4
        return new Response($serializedEntity);
147
    }
148
149
}
150