Passed
Push — develop ( 7c6c89...89f4d5 )
by Daniel
06:08
created

ApiContextBuilder::createFromRequest()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 13
nc 4
nop 3
dl 0
loc 20
ccs 0
cts 12
cp 0
crap 30
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace Silverback\ApiComponentBundle\Serializer;
4
5
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
6
use Silverback\ApiComponentBundle\Entity\Component\AbstractComponent;
7
use Silverback\ApiComponentBundle\Entity\Content\AbstractContent;
8
use Silverback\ApiComponentBundle\Entity\Content\ComponentLocation;
9
use Silverback\ApiComponentBundle\Entity\Layout\Layout;
10
use Silverback\ApiComponentBundle\Entity\Navigation\AbstractNavigation;
11
use Silverback\ApiComponentBundle\Entity\Navigation\AbstractNavigationItem;
12
use Silverback\ApiComponentBundle\Entity\Navigation\Route\Route;
13
use Symfony\Component\HttpFoundation\Request;
14
15
class ApiContextBuilder implements SerializerContextBuilderInterface
16
{
17
    /**
18
     * @var string[][]
19
     */
20
    public const CLASS_GROUP_MAPPING = [
21
        AbstractComponent::class => ['component'],
22
        AbstractNavigation::class => ['component'],
23
        ComponentLocation::class => ['component'],
24
        AbstractNavigationItem::class => ['component_item'],
25
        AbstractContent::class => ['content'],
26
        Route::class => ['route'],
27
        Layout::class => ['layout']
28
    ];
29
30
    /**
31
     * @var SerializerContextBuilderInterface
32
     */
33
    private $decorated;
34
35
    public function __construct(SerializerContextBuilderInterface $decorated)
36
    {
37
        $this->decorated = $decorated;
38
    }
39
40
    /**
41
     * @param string $group
42
     * @param bool $normalization
43
     * @param null|string $operation
44
     * @return array
45
     */
46
    private function getGroupNames(string $group, bool $normalization, ?string $operation): array
47
    {
48
        $groups = [$group, $group . ($normalization ? '_read' : '_write')];
49
        if ($operation) {
50
            $groups[] = "${group}_${operation}";
51
        }
52
        return $groups;
53
    }
54
55
    /**
56
     * @param $className
57
     * @param $matchClassName
58
     * @return bool
59
     */
60
    private function matchClass($className, $matchClassName): bool
61
    {
62
        return $className === $matchClassName || is_subclass_of($className, $matchClassName);
63
    }
64
65
    /**
66
     * @param string $subject
67
     * @param bool $normalization
68
     * @param string $operation
69
     * @return array
70
     */
71
    private function getGroups(string $subject, bool $normalization, ?string $operation): array
72
    {
73
        /** @var string[] $groups */
74
        $groups = [];
75
        foreach (self::CLASS_GROUP_MAPPING as $class=>$groupMapping) {
76
            if ($this->matchClass($subject, $class)) {
77
                foreach ($groupMapping as $group) {
78
                    $groups[] = $this->getGroupNames($group, $normalization, $operation);
79
                }
80
            }
81
        }
82
        return $groups;
83
    }
84
85
    /**
86
     * @param Request $request
87
     * @param bool $normalization
88
     * @param array|null $extractedAttributes
89
     * @return array
90
     * @throws \ApiPlatform\Core\Exception\RuntimeException
91
     */
92
    public function createFromRequest(Request $request, bool $normalization, array $extractedAttributes = null) : array
93
    {
94
        $context = $this->decorated->createFromRequest($request, $normalization, $extractedAttributes);
95
        if (isset($context['groups']) && \in_array('none', $context['groups'], true)) {
96
            return $context;
97
        }
98
        $subject = $request->attributes->get('_api_resource_class');
99
        $operation = $context['item_operation_name'] ?? null;
100
        $groups = $this->getGroups($subject, $normalization, $operation);
101
102
        if (\count($groups)) {
103
            if (!isset($context['groups'])) {
104
                $context['groups'] = ['default'];
105
            } else {
106
                $context['groups'][] = ['default'];
107
            }
108
            $context['groups'] = array_merge($context['groups'], ...$groups);
0 ignored issues
show
Bug introduced by
$groups is expanded, but the parameter $array2 of array_merge() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

108
            $context['groups'] = array_merge($context['groups'], /** @scrutinizer ignore-type */ ...$groups);
Loading history...
109
        }
110
111
        return $context;
112
    }
113
}
114