Passed
Push — feature/initial-implementation ( f3915b...fbd338 )
by Fike
02:22
created

Mapping::from()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AmaTeam\ElasticSearch\Mapping;
6
7
use AmaTeam\ElasticSearch\API\Mapping\MappingInterface;
8
use AmaTeam\ElasticSearch\Mapping\Type\RootType;
9
use stdClass;
10
11
class Mapping implements MappingInterface
12
{
13
    const PROPERTIES_KEY = 'properties';
14
    const TYPE_KEY = 'type';
15
    /**
16
     * @var string
17
     */
18
    private $type;
19
    /**
20
     * @var array
21
     */
22
    private $parameters = [];
23
    /**
24
     * @var MappingInterface[]
25
     */
26
    private $properties = [];
27
28
    /**
29
     * @param string $type
30
     */
31
    public function __construct(string $type = null)
32
    {
33
        $this->type = $type;
34
    }
35
36
    /**
37
     * @return string
38
     */
39
    public function getType(): ?string
40
    {
41
        return $this->type;
42
    }
43
44
    /**
45
     * @param string $type
46
     * @return $this
47
     */
48
    public function setType(string $type)
49
    {
50
        $this->type = $type;
51
        return $this;
52
    }
53
54
    public function hasParameter(string $name): bool
55
    {
56
        return isset($this->parameters[$name]);
57
    }
58
59
    /**
60
     * @return array
61
     */
62
    public function getParameters(): array
63
    {
64
        return $this->parameters;
65
    }
66
67
    public function getParameter(string $name)
68
    {
69
        return $this->parameters[$name] ?? null;
70
    }
71
72
    /**
73
     * @param array $parameters
74
     * @return $this
75
     */
76
    public function setParameters(array $parameters)
77
    {
78
        $this->parameters = $parameters;
79
        return $this;
80
    }
81
82
    public function setParameter(string $parameter, $value)
83
    {
84
        $this->parameters[$parameter] = $value;
85
        return $this;
86
    }
87
88
    public function hasProperty(string $name): bool
89
    {
90
        return isset($this->properties[$name]);
91
    }
92
93
    /**
94
     * @return MappingInterface[]
95
     */
96
    public function getProperties(): array
97
    {
98
        return $this->properties;
99
    }
100
101
    public function getProperty(string $name): ?MappingInterface
102
    {
103
        return $this->properties[$name] ?? null;
104
    }
105
106
    /**
107
     * @param MappingInterface[] $properties
108
     * @return $this
109
     */
110
    public function setProperties(array $properties)
111
    {
112
        $this->properties = $properties;
113
        return $this;
114
    }
115
116
    public function setProperty(string $property, MappingInterface $mapping): Mapping
117
    {
118
        $this->properties[$property] = $mapping;
119
        return $this;
120
    }
121
122
    public function removeProperty(string $property): Mapping
123
    {
124
        unset($this->properties[$property]);
125
        return $this;
126
    }
127
128
    public static function asObject(MappingInterface $source)
129
    {
130
        $result = new stdClass();
131
        foreach ($source->getParameters() as $parameter => $value) {
132
            $result->$parameter = $value;
133
        }
134
        if (!empty($source->getProperties())) {
135
            $properties = new stdClass();
136
            foreach ($source->getProperties() as $property => $mapping) {
137
                $properties->$property = static::asObject($mapping);
138
            }
139
            $result->properties = $properties;
140
        }
141
        if ($source->getType() && $source->getType() !== RootType::ID) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $source->getType() 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...
142
            $result->type = $source->getType();
143
        }
144
        return $result;
145
    }
146
147
    public static function asArray(MappingInterface $source): array
148
    {
149
        $result = [];
150
        foreach ($source->getParameters() as $parameter => $value) {
151
            $result[$parameter] = $value;
152
        }
153
        if (!empty($source->getProperties())) {
154
            $properties = [];
155
            foreach ($source->getProperties() as $property => $mapping) {
156
                $properties[$property] = static::asArray($mapping);
157
            }
158
            $result[self::PROPERTIES_KEY] = $properties;
159
        }
160
        if ($source->getType() && $source->getType() !== RootType::ID) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $source->getType() 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...
161
            $result[self::TYPE_KEY] = $source->getType();
162
        }
163
        return $result;
164
    }
165
166
    public static function merge(MappingInterface... $sources): Mapping
167
    {
168
        $target = new Mapping();
169
        foreach ($sources as $source) {
170
            if ($source->getType()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $source->getType() 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...
171
                $target->setType($source->getType());
172
            }
173
            foreach ($source->getParameters() as $parameter => $value) {
174
                $target->setParameter($parameter, $value);
175
            }
176
            foreach ($source->getProperties() as $property => $mapping) {
177
                $candidate = $target->getProperty($property);
178
                $target->setProperty($property, $candidate ? static::merge($candidate, $mapping) : $mapping);
179
            }
180
        }
181
        return $target;
182
    }
183
184
    public static function from(MappingInterface $mapping): Mapping
185
    {
186
        return static::merge($mapping);
187
    }
188
189
    public static function fromArray(array $mapping): Mapping
190
    {
191
        $target = new Mapping();
192
        if (isset($mapping[self::TYPE_KEY])) {
193
            $target->setType($mapping[self::TYPE_KEY]);
194
        }
195
        if (isset($mapping[self::PROPERTIES_KEY]) && is_array($mapping[self::PROPERTIES_KEY])) {
196
            foreach ($mapping[self::PROPERTIES_KEY] as $name => $property) {
197
                $target->setProperty($name, static::fromArray($property));
198
            }
199
        }
200
        foreach ($mapping as $parameter => $value) {
201
            if ($parameter === self::TYPE_KEY || $parameter === self::PROPERTIES_KEY) {
202
                continue;
203
            }
204
            $target->setParameter($parameter, $value);
205
        }
206
        return $target;
207
    }
208
}
209