Passed
Push — master ( 6b66e0...046ff6 )
by Daniel
07:24
created

ApiContextBuilder::getGroups()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 5

Importance

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