Completed
Push — master ( 454f7d...fc2d7f )
by Eric
02:39
created

loadPropertyMetadataAlias()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 17
Code Lines 9

Duplication

Lines 17
Ratio 100 %

Importance

Changes 0
Metric Value
dl 17
loc 17
rs 9.2
c 0
b 0
f 0
cc 4
eloc 9
nc 3
nop 2
1
<?php
2
3
/*
4
 * This file is part of the Ivory Serializer package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ivory\Serializer\Mapping\Loader;
13
14
use Ivory\Serializer\Mapping\ClassMetadataInterface;
15
use Ivory\Serializer\Mapping\PropertyMetadata;
16
use Ivory\Serializer\Mapping\PropertyMetadataInterface;
17
use Ivory\Serializer\Type\Parser\TypeParser;
18
use Ivory\Serializer\Type\Parser\TypeParserInterface;
19
20
/**
21
 * @author GeLo <[email protected]>
22
 */
23
abstract class AbstractClassMetadataLoader implements ClassMetadataLoaderInterface
24
{
25
    /**
26
     * @var TypeParserInterface
27
     */
28
    private $typeParser;
29
30
    /**
31
     * @var mixed[][]
32
     */
33
    private $data = [];
34
35
    /**
36
     * @param TypeParserInterface|null $typeParser
37
     */
38
    public function __construct(TypeParserInterface $typeParser = null)
39
    {
40
        $this->typeParser = $typeParser ?: new TypeParser();
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function loadClassMetadata(ClassMetadataInterface $classMetadata)
47
    {
48
        $class = $classMetadata->getName();
49
50
        if (!array_key_exists($class, $this->data)) {
51
            $this->data[$class] = $this->loadData($class);
52
        }
53
54
        if (!is_array($data = $this->data[$class])) {
55
            return false;
56
        }
57
58
        $this->doLoadClassMetadata($classMetadata, $data);
59
60
        return true;
61
    }
62
63
    /**
64
     * @param string $class
65
     *
66
     * @return mixed[]|null
67
     */
68
    abstract protected function loadData($class);
69
70
    /**
71
     * @param ClassMetadataInterface $classMetadata
72
     * @param mixed[]                $data
73
     *
74
     * @return bool
75
     */
76
    private function doLoadClassMetadata(ClassMetadataInterface $classMetadata, array $data)
77
    {
78
        if (!isset($data['properties']) || empty($data['properties'])) {
79
            throw new \InvalidArgumentException(sprintf(
80
                'No mapping properties found for "%s".',
81
                $classMetadata->getName()
82
            ));
83
        }
84
85
        foreach ($data['properties'] as $property => $value) {
86
            $propertyMetadata = $classMetadata->getProperty($property) ?: new PropertyMetadata($property);
87
            $this->loadPropertyMetadata($propertyMetadata, $value);
88
            $classMetadata->addProperty($propertyMetadata);
89
        }
90
    }
91
92
    /**
93
     * @param PropertyMetadataInterface $propertyMetadata
94
     * @param mixed                     $data
95
     */
96
    private function loadPropertyMetadata(PropertyMetadataInterface $propertyMetadata, $data)
97
    {
98
        if (!is_array($data)) {
99
            return;
100
        }
101
102
        if (array_key_exists('alias', $data)) {
103
            $this->loadPropertyMetadataAlias($propertyMetadata, $data['alias']);
104
        }
105
106
        if (array_key_exists('type', $data)) {
107
            $this->loadPropertyMetadataType($propertyMetadata, $data['type']);
108
        }
109
110
        if (array_key_exists('since', $data)) {
111
            $this->loadPropertyMetadataSinceVersion($propertyMetadata, $data['since']);
112
        }
113
114
        if (array_key_exists('until', $data)) {
115
            $this->loadPropertyMetadataUntilVersion($propertyMetadata, $data['until']);
116
        }
117
118
        if (array_key_exists('max_depth', $data)) {
119
            $this->loadPropertyMetadataMaxDepth($propertyMetadata, $data['max_depth']);
120
        }
121
122
        if (array_key_exists('groups', $data)) {
123
            $this->loadPropertyMetadataGroups($propertyMetadata, $data['groups']);
124
        }
125
    }
126
127
    /**
128
     * @param PropertyMetadataInterface $propertyMetadata
129
     * @param string                    $alias
130
     */
131 View Code Duplication
    private function loadPropertyMetadataAlias(PropertyMetadataInterface $propertyMetadata, $alias)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
132
    {
133
        if (!is_string($alias)) {
134
            throw new \InvalidArgumentException(sprintf(
135
                'The mapping property alias must be a non empty string, got "%s".',
136
                is_object($alias) ? get_class($alias) : gettype($alias)
137
            ));
138
        }
139
140
        $alias = trim($alias);
141
142
        if (empty($alias)) {
143
            throw new \InvalidArgumentException('The mapping property alias must be a non empty string.');
144
        }
145
146
        $propertyMetadata->setAlias($alias);
147
    }
148
149
    /**
150
     * @param PropertyMetadataInterface $propertyMetadata
151
     * @param string                    $type
152
     */
153
    private function loadPropertyMetadataType(PropertyMetadataInterface $propertyMetadata, $type)
154
    {
155
        if (!is_string($type)) {
156
            throw new \InvalidArgumentException(sprintf(
157
                'The mapping property type must be a non empty string, got "%s".',
158
                is_object($type) ? get_class($type) : gettype($type)
159
            ));
160
        }
161
162
        $propertyMetadata->setType($this->typeParser->parse($type));
163
    }
164
165
    /**
166
     * @param PropertyMetadataInterface $propertyMetadata
167
     * @param string                    $version
168
     */
169 View Code Duplication
    private function loadPropertyMetadataSinceVersion(PropertyMetadataInterface $propertyMetadata, $version)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
170
    {
171
        if (!is_string($version)) {
172
            throw new \InvalidArgumentException(sprintf(
173
                'The mapping property since version must be a non empty string, got "%s".',
174
                is_object($version) ? get_class($version) : gettype($version)
175
            ));
176
        }
177
178
        $version = trim($version);
179
180
        if (empty($version)) {
181
            throw new \InvalidArgumentException('The mapping property since version must be a non empty string.');
182
        }
183
184
        $propertyMetadata->setSinceVersion($version);
185
    }
186
187
    /**
188
     * @param PropertyMetadataInterface $propertyMetadata
189
     * @param string                    $version
190
     */
191 View Code Duplication
    private function loadPropertyMetadataUntilVersion(PropertyMetadataInterface $propertyMetadata, $version)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
192
    {
193
        if (!is_string($version)) {
194
            throw new \InvalidArgumentException(sprintf(
195
                'The mapping property until version must be a non empty string, got "%s".',
196
                is_object($version) ? get_class($version) : gettype($version)
197
            ));
198
        }
199
200
        $version = trim($version);
201
202
        if (empty($version)) {
203
            throw new \InvalidArgumentException('The mapping property until version must be a non empty string.');
204
        }
205
206
        $propertyMetadata->setUntilVersion($version);
207
    }
208
209
    /**
210
     * @param PropertyMetadataInterface $propertyMetadata
211
     * @param string|int                $maxDepth
212
     */
213
    private function loadPropertyMetadataMaxDepth(PropertyMetadataInterface $propertyMetadata, $maxDepth)
214
    {
215
        if (!is_int($maxDepth) && !is_string($maxDepth) && !ctype_digit($maxDepth)) {
216
            throw new \InvalidArgumentException(sprintf(
217
                'The mapping property max depth must be a positive integer, got "%s".',
218
                is_object($maxDepth) ? get_class($maxDepth) : gettype($maxDepth)
219
            ));
220
        }
221
222
        $maxDepth = (int) $maxDepth;
223
224
        if ($maxDepth <= 0) {
225
            throw new \InvalidArgumentException(sprintf(
226
                'The mapping property max depth must be a positive integer, got "%d".',
227
                $maxDepth
228
            ));
229
        }
230
231
        $propertyMetadata->setMaxDepth($maxDepth);
232
    }
233
234
    /**
235
     * @param PropertyMetadataInterface $propertyMetadata
236
     * @param string[]                  $groups
237
     */
238
    private function loadPropertyMetadataGroups(PropertyMetadataInterface $propertyMetadata, $groups)
239
    {
240
        if (!is_array($groups)) {
241
            throw new \InvalidArgumentException(sprintf(
242
                'The mapping property groups must be an array of non empty strings, got "%s".',
243
                is_object($groups) ? get_class($groups) : gettype($groups)
244
            ));
245
        }
246
247
        foreach ($groups as $group) {
248
            if (!is_string($group)) {
249
                throw new \InvalidArgumentException(sprintf(
250
                    'The mapping property groups must be an array of non empty strings, got "%s".',
251
                    is_object($group) ? get_class($group) : gettype($group)
252
                ));
253
            }
254
255
            $group = trim($group);
256
257
            if (empty($group)) {
258
                throw new \InvalidArgumentException(
259
                    'The mapping property groups must be an array of non empty strings.'
260
                );
261
            }
262
263
            $propertyMetadata->addGroup($group);
264
        }
265
    }
266
}
267