Completed
Pull Request — master (#1198)
by Martin Poirier
11:27
created

GroupsExclusionStrategy::buildPathFromContext()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace JMS\Serializer\Exclusion;
6
7
use JMS\Serializer\Context;
8
use JMS\Serializer\Metadata\ClassMetadata;
9
use JMS\Serializer\Metadata\PropertyMetadata;
10
11
final class GroupsExclusionStrategy implements ExclusionStrategyInterface
12
{
13
    public const DEFAULT_GROUP = 'Default';
14
15
    /**
16
     * @var array<string,array<string,boolean>>
17
     */
18
    private $parsedGroups = [];
19 33
20
    /**
21 33
     * @var bool
22 4
     */
23
    private $nestedGroups = false;
24
25 33
    public function __construct(array $groups)
26 33
    {
27 2
        $this->prepare($groups, 'root');
28 33
    }
29
30
    private function prepare(array $groups, $path)
31
    {
32 33
        $currentGroups = [];
33 2
        foreach ($groups as $key => $value) {
34
            if (is_string($key) && is_array($value)) {
35 31
                $this->nestedGroups = true;
36 31
                $this->prepare($value, $path . '.' . $key);
37
                continue;
38
            }
39 33
40
            $currentGroups[$value] = true;
41
        }
42
43
        if (empty($currentGroups)) {
44 15
            $currentGroups[self::DEFAULT_GROUP] = true;
45
        }
46 15
47
        $this->parsedGroups[$path] = $currentGroups;
48
    }
49
50
    /**
51
     * {@inheritDoc}
52 33
     */
53
    public function shouldSkipClass(ClassMetadata $metadata, Context $navigatorContext): bool
54 33
    {
55 2
        return false;
56
    }
57 2
58 2
    /**
59
     * {@inheritDoc}
60
     */
61 2
    public function shouldSkipProperty(PropertyMetadata $property, Context $navigatorContext): bool
62
    {
63
        $groups = $property->groups ?: [self::DEFAULT_GROUP];
64 31
65 9
        if (!$this->nestedGroups) {
66
            // Group are not nested so we
67
            $path = 'root';
68 29
        } else {
69 29
            $path = $this->buildPathFromContext($navigatorContext);
70 29
        }
71
72
        if(!isset($this->parsedGroups[$path])) {
73 18
            // If we reach that path it's because we were allowed so we fallback on default group
74
            $this->parsedGroups[$path] = [self::DEFAULT_GROUP => true];
75
        }
76
77 2
        $againstGroups = $this->parsedGroups[$path];
78
79 2
        foreach ($groups as $group) {
80 2
            if (isset($againstGroups[$group])) {
81 2
                return false;
82
            }
83
        }
84
85 2
        return true;
86
    }
87
88 2
    private function buildPathFromContext(Context $navigatorContext): string
89
    {
90 2
        $path = $navigatorContext->getCurrentPath();
91
        array_unshift($path, 'root');
92 2
        return implode('.', $path);
93 2
    }
94 2
95 2
    public function getGroupsFor(Context $navigatorContext): array
96
    {
97
        if (!$this->nestedGroups) {
98 2
            return array_keys($this->parsedGroups['root']);
99
        }
100
101
        $path = $this->buildPathFromContext($navigatorContext);
102 2
103
        if (!isset($this->parsedGroups[$path])) {
104
            return [self::DEFAULT_GROUP];
105 2
        }
106
107
        return array_keys($this->parsedGroups[$path]);
108
    }
109
}
110