Passed
Push — master ( f721ff...336c17 )
by Asmir
05:36 queued 03:18
created

GroupsExclusionStrategy::shouldSkipProperty()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
eloc 12
nc 6
nop 2
dl 0
loc 22
ccs 12
cts 12
cp 1
crap 7
rs 8.8333
c 0
b 0
f 0
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
17
     */
18
    private $groups = [];
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
        if (empty($groups)) {
28 33
            $groups = [self::DEFAULT_GROUP];
29
        }
30
31
        foreach ($groups as $group) {
32 33
            if (is_array($group)) {
33 2
                $this->nestedGroups = true;
34
                break;
35 31
            }
36 31
        }
37
38
        if ($this->nestedGroups) {
39 33
            $this->groups = $groups;
40
        } else {
41
            foreach ($groups as $group) {
42
                $this->groups[$group] = true;
43
            }
44 15
        }
45
    }
46 15
47
    public function shouldSkipClass(ClassMetadata $metadata, Context $navigatorContext): bool
48
    {
49
        return false;
50
    }
51
52 33
    public function shouldSkipProperty(PropertyMetadata $property, Context $navigatorContext): bool
53
    {
54 33
        if ($this->nestedGroups) {
55 2
            $groups = $this->getGroupsFor($navigatorContext);
56
57 2
            if (!$property->groups) {
58 2
                return !in_array(self::DEFAULT_GROUP, $groups);
59
            }
60
61 2
            return $this->shouldSkipUsingGroups($property, $groups);
62
        } else {
63
            if (!$property->groups) {
64 31
                return !isset($this->groups[self::DEFAULT_GROUP]);
65 9
            }
66
67
            foreach ($property->groups as $group) {
68 29
                if (is_scalar($group) && isset($this->groups[$group])) {
69 29
                    return false;
70 29
                }
71
            }
72
73 18
            return true;
74
        }
75
    }
76
77 2
    private function shouldSkipUsingGroups(PropertyMetadata $property, array $groups): bool
78
    {
79 2
        foreach ($property->groups as $group) {
80 2
            if (in_array($group, $groups)) {
81 2
                return false;
82
            }
83
        }
84
85 2
        return true;
86
    }
87
88 2
    public function getGroupsFor(Context $navigatorContext): array
89
    {
90 2
        if (!$this->nestedGroups) {
91
            return array_keys($this->groups);
92 2
        }
93 2
94 2
        $paths = $navigatorContext->getCurrentPath();
95 2
        $groups = $this->groups;
96
        foreach ($paths as $index => $path) {
97
            if (!array_key_exists($path, $groups)) {
98 2
                if ($index > 0) {
99
                    $groups = [self::DEFAULT_GROUP];
100
                } else {
101
                    $groups = array_filter($groups, 'is_string') ?: [self::DEFAULT_GROUP];
102 2
                }
103
104
                break;
105 2
            }
106
107
            $groups = $groups[$path];
108
            if (!array_filter($groups, 'is_string')) {
109
                $groups += [self::DEFAULT_GROUP];
110
            }
111
        }
112
113
        return $groups;
114
    }
115
}
116