/
Normalizer.php
142 lines (117 loc) · 3.85 KB
/
Normalizer.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php
/**
* This file is part of the serializer project
*
* (c) Sergey Kolodyazhnyy <sergey.kolodyazhnyy@gmail.com>
*
*/
namespace Bcn\Component\Serializer;
class Normalizer
{
/**
* @param mixed $origin
* @param Definition $definition
* @return array|string
*/
public function normalize($origin, Definition $definition)
{
if ($definition->isArray()) {
return $this->normalizeArray($origin, $definition);
}
if ($definition->isObject()) {
return $this->normalizeObject($origin, $definition);
}
return $definition->extract($origin);
}
/**
* @param mixed $origin
* @param Definition $definition
* @return array
*/
protected function normalizeObject(&$origin, Definition $definition)
{
$object = $definition->extract($origin);
if ($object === null) {
return null;
}
$normalized = array();
foreach ($definition->getProperties() as $propertyName => $propertyDefinition) {
$normalized[$propertyName] = $this->normalize($object, $propertyDefinition);
}
return $normalized;
}
/**
* @param mixed $origin
* @param Definition $definition
* @return array
*/
protected function normalizeArray(&$origin, Definition $definition)
{
$collection = $definition->extract($origin);
if (!is_array($collection) && !$collection instanceof \Traversable) {
$collection = array();
}
$normalized = array();
foreach ($collection as $index => $entry) {
$normalized[$index] = $this->normalize($entry, $definition->getPrototype());
}
return $normalized;
}
/**
* @param mixed $data
* @param Definition $definition
* @param mixed $origin
* @return null
*/
public function denormalize($data, Definition $definition, &$origin = null)
{
if ($definition->isArray()) {
$this->denormalizeArray($data, $definition, $origin);
}
if ($definition->isObject()) {
$this->denormalizeObject($data, $definition, $origin);
}
if ($definition->isScalar()) {
$definition->settle($origin, $data);
}
return $origin;
}
/**
* @param mixed $data
* @param Definition $definition
* @param mixed $origin
*/
protected function denormalizeArray($data, Definition $definition, &$origin)
{
$collection = ($origin !== null) ? $definition->extract($origin) : $definition->create($origin);
$prototype = $definition->getPrototype();
if (!is_array($data) && !$data instanceof \Traversable) {
$data = array();
}
foreach ($data as $index => $entry) {
$item = isset($collection[$index]) ? $collection[$index] : $prototype->create($origin);
$definition->settleKey($item, $index);
$collection[$index] = $this->denormalize($entry, $prototype, $item);
}
$definition->settle($origin, $collection);
}
/**
* @param mixed $data
* @param Definition $definition
* @param mixed $origin
* @return array
*/
protected function denormalizeObject($data, Definition $definition, &$origin)
{
if ($data === null) {
$definition->settle($origin, null);
return;
}
$object = $definition->extract($origin) ?: $definition->create($origin);
foreach ($definition->getProperties() as $propertyName => $propertyDefinition) {
$propertyData = isset($data[$propertyName]) ? $data[$propertyName] : null;
$this->denormalize($propertyData, $propertyDefinition, $object);
}
$definition->settle($origin, $object);
}
}