Passed
Push — feature/initial-implementation ( 70fbec...2d1ee1 )
by Fike
02:35
created

ClassMapping::merge()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 12
nc 9
nop 1
dl 0
loc 16
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AmaTeam\ElasticSearch\API\Entity\Mapping;
6
7
use AmaTeam\ElasticSearch\API\Entity\Mapping\PropertyMapping as PropertyDescriptor;
8
use AmaTeam\ElasticSearch\Utility\Classes;
9
10
class ClassMapping implements ClassMappingInterface
11
{
12
    /**
13
     * @var string
14
     */
15
    private $entityName;
16
    /**
17
     * @var PropertyDescriptor[]
18
     */
19
    private $properties = [];
20
    /**
21
     * @var ClassMappingView
22
     */
23
    private $defaultView;
24
    /**
25
     * @var ClassMappingView[]
26
     */
27
    private $views = [];
28
29
    /**
30
     * @SuppressWarnings(PHPMD.LongVariable)
31
     * @var bool
32
     */
33
    private $inheritsParentMapping = true;
34
    /**
35
     * @SuppressWarnings(PHPMD.LongVariable)
36
     * @var string[]
37
     */
38
    private $ignoredParentProperties;
39
40
    /**
41
     * @param string $className
42
     */
43
    public function __construct(string $className = null)
44
    {
45
        if ($className) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $className of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
46
            $this->setEntityName($className);
47
        }
48
        $this->defaultView = new ClassMappingView();
49
    }
50
51
    /**
52
     * @return string
53
     */
54
    public function getEntityName(): string
55
    {
56
        return $this->entityName;
57
    }
58
59
    /**
60
     * @param string $entityName
61
     * @return $this
62
     */
63
    public function setEntityName(string $entityName)
64
    {
65
        $this->entityName = Classes::normalizeAbsoluteName($entityName);
66
        return $this;
67
    }
68
69
    /**
70
     * @return PropertyDescriptor[]
71
     */
72
    public function getProperties(): array
73
    {
74
        return $this->properties;
75
    }
76
77
    /**
78
     * @param PropertyDescriptor[] $properties
79
     * @return $this
80
     */
81
    public function setProperties(array $properties)
82
    {
83
        $this->properties = $properties;
84
        return $this;
85
    }
86
87
    public function getProperty(string $name): PropertyMappingInterface
88
    {
89
        return $this->properties[$name] ?? null;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->properties[$name] ?? null could return the type null which is incompatible with the type-hinted return AmaTeam\ElasticSearch\AP...ropertyMappingInterface. Consider adding an additional type-check to rule them out.
Loading history...
90
    }
91
92
    public function requestProperty(string $name): PropertyMappingInterface
93
    {
94
        if (!isset($this->properties[$name])) {
95
            $this->properties[$name] = new PropertyMapping($this->entityName, $name);
96
        }
97
        return $this->properties[$name];
98
    }
99
100
    public function setProperty(string $name, PropertyMappingInterface $property): ClassMapping
101
    {
102
        $this->properties[$name] = $property;
103
        return $this;
104
    }
105
106
    /**
107
     * @return ClassMappingViewInterface
108
     */
109
    public function getDefaultView(): ClassMappingViewInterface
110
    {
111
        return $this->defaultView;
112
    }
113
114
    /**
115
     * @param ClassMappingView $defaultView
116
     * @return $this
117
     */
118
    public function setDefaultView(ClassMappingView $defaultView)
119
    {
120
        $this->defaultView = $defaultView;
121
        return $this;
122
    }
123
124
    /**
125
     * @return ClassMappingView[]
126
     */
127
    public function getViews(): array
128
    {
129
        return $this->views;
130
    }
131
132
    public function getView(string $name): ?ClassMappingViewInterface
133
    {
134
        return $this->views[$name] ?? null;
135
    }
136
137
    public function requestView(string $name): ClassMappingViewInterface
138
    {
139
        if (!isset($this->views[$name])) {
140
            $this->views[$name] = new ClassMappingView();
141
        }
142
        return $this->views[$name];
143
    }
144
145
    /**
146
     * @param string[] ...$names
147
     * @return ClassMappingView[]
148
     */
149
    public function requestViews(string ...$names): array
150
    {
151
        return array_map([$this, 'requestView'], $names);
152
    }
153
154
    /**
155
     * @param ClassMappingView[] $views
156
     * @return $this
157
     */
158
    public function setViews(array $views)
159
    {
160
        $this->views = $views;
161
        return $this;
162
    }
163
164
    public function setView(string $name, ClassMappingViewInterface $view): ClassMapping
165
    {
166
        $this->views[$name] = $view;
167
        return $this;
168
    }
169
170
    /**
171
     * @return bool
172
     */
173
    public function inheritsParentMapping(): bool
174
    {
175
        return $this->inheritsParentMapping;
176
    }
177
178
    /**
179
     * @param bool $inheritsParentMapping
180
     * @return ClassMappingInterface
181
     */
182
    public function setInheritsParentMapping(bool $inheritsParentMapping): ClassMappingInterface
183
    {
184
        $this->inheritsParentMapping = $inheritsParentMapping;
185
        return $this;
186
    }
187
188
    /**
189
     * @return string[]
190
     */
191
    public function getIgnoredParentProperties(): ?array
192
    {
193
        return $this->ignoredParentProperties;
194
    }
195
196
    /**
197
     * @param string[] $ignoredParentProperties
198
     * @return ClassMappingInterface
199
     */
200
    public function setIgnoredParentProperties(string ...$ignoredParentProperties): ClassMappingInterface
201
    {
202
        $this->ignoredParentProperties = $ignoredParentProperties;
203
        return $this;
204
    }
205
206
    public static function merge(ClassMappingInterface ...$sources)
207
    {
208
        $target = new ClassMapping();
209
        foreach ($sources as $source) {
210
            $target->setEntityName($source->getEntityName());
211
            if ($source->getIgnoredParentProperties() !== null) {
212
                $target->setIgnoredParentProperties(...$source->getIgnoredParentProperties());
213
            }
214
            $target->setInheritsParentMapping($source->inheritsParentMapping());
215
            $defaultView = ClassMappingView::merge($target->getDefaultView(), $source->getDefaultView());
216
            $target->setDefaultView($defaultView);
217
            foreach ($source->getViews() as $name => $view) {
218
                $target->setView($name, ClassMappingView::merge($target->requestView($name), $view));
219
            }
220
            foreach ($source->getProperties() as $name => $property) {
221
                $target->setProperty($name, PropertyMapping::merge($target->requestProperty($name), $property));
222
            }
223
        }
224
    }
225
}
226