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

GenericEntityListingController   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 146
Duplicated Lines 36.99 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 97.78%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 8
dl 54
loc 146
ccs 44
cts 45
cp 0.9778
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 Webmozart\Assert\Assert;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpFoundation\Response;
19
use Addiks\SymfonyGenerics\Services\ArgumentCompilerInterface;
20
use Addiks\SymfonyGenerics\Controllers\ApplyDataTemplateTrait;
21
use Symfony\Component\Serializer\Encoder\EncoderInterface;
22
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
23
use ErrorException;
24
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
25
26
final class GenericEntityListingController
27
{
28
    use ApplyDataTemplateTrait;
29
30
    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...
31
32
    private ArgumentCompilerInterface $argumentCompiler;
33
34
    /** @var class-string */
35
    private string $entityClass;
36
37
    private array $criteria;
38
39
    private ?string $authorizationAttribute;
40
41
    private string $format;
42
43
    private ?EncoderInterface $encoder;
44
45
    private ?NormalizerInterface $normalizer;
46
47
    private ?array $dataTemplate;
48
49
    public function __construct(
50
        ControllerHelperInterface $controllerHelper,
51
        ArgumentCompilerInterface $argumentCompiler,
52
        array $options
53
    ) {
54
        Assert::keyExists($options, 'entity-class');
55
        Assert::classExists($options['entity-class']);
56
57
        $options = array_merge([
58
            'format' => 'json',
59
            'criteria' => [],
60
            'authorization-attribute' => null,
61
            'encoder' => null,
62
            'normalizer' => null,
63
            'data-template' => null,
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
69
        $this->controllerHelper = $controllerHelper;
70
        $this->argumentCompiler = $argumentCompiler;
71
        $this->entityClass = $options['entity-class'];
72
        $this->criteria = $options['criteria'];
73
        $this->encoder = $options['encoder'];
74
        $this->normalizer = $options['normalizer'];
75 10
        $this->format = $options['format'];
76
        $this->dataTemplate = $options['data-template'];
77
        $this->authorizationAttribute = $options['authorization-attribute'];
78
    }
79
80 10
    public function __invoke(): Response
81 10
    {
82 9
        /** @var Request $request */
83
        $request = $this->controllerHelper->getCurrentRequest();
84 8
85 8
        Assert::isInstanceOf($request, Request::class, "Cannot use controller outside of request-scope!");
86
87
        return $this->listEntities($request);
88
    }
89
90
    public function listEntities(Request $request): Response
91 8
    {
92
        if (!is_null($this->authorizationAttribute)) {
93 8
            $this->controllerHelper->denyAccessUnlessGranted($this->authorizationAttribute, $request);
94 7
        }
95
96 6
        /** @var array $criteria */
97 6
        $criteria = $this->argumentCompiler->buildArguments($this->criteria);
98 6
99 6
        /** @var array<object> $entities */
100 6
        $entities = $this->controllerHelper->findEntities($this->entityClass, $criteria);
101 6
102 6
        /** @var array<int, array> $resultData */
103 6
        $resultEntries = array();
104 6
105 6
        foreach ($entities as $entity) {
106
            /** @var object $entity */
107 2
108
            /** @var array $normalizedEntity */
109
            $normalizedEntity = array();
110 2
111
            if ($this->normalizer instanceof NormalizerInterface) {
112 2
                $normalizedEntity = $this->normalizer->normalize($entity);
113
114 1
            } else {
115
                $normalizer = new ObjectNormalizer();
116
117 4
                $normalizedEntity = $normalizer->normalize($entity);
118
            }
119 4
120 1
            if (!is_array($normalizedEntity)) {
121
                throw new ErrorException("Result of normalize process must be an array!");
122
            }
123
124 3
            if (!is_null($this->dataTemplate)) {
125
                $normalizedEntity = $this->applyDataTemplate($normalizedEntity, $this->dataTemplate);
126
            }
127 3
128
            $resultEntries[] = $normalizedEntity;
129
        }
130 3
131
        /** @var string $serializedEntity */
132 3
        $serializedEntity = "";
133
134
        if ($this->encoder instanceof EncoderInterface) {
135
            $serializedEntity = $this->encoder->encode($resultEntries, $this->format);
136 3
137
        } else {
138 3
            $serializedEntity = json_encode($resultEntries);
139 1
        }
140
141
        return new Response($serializedEntity);
142 2
    }
143
144
}
145