1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace WebComplete\core\utils\hydrator; |
4
|
|
|
|
5
|
|
|
use ReflectionProperty; |
6
|
|
|
|
7
|
|
|
class Hydrator implements HydratorInterface |
8
|
|
|
{ |
9
|
|
|
|
10
|
|
|
private $reflections = []; |
11
|
|
|
private $reflectionsPropertyList = []; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* create or update object properties with data |
15
|
|
|
* |
16
|
|
|
* @param array $data |
17
|
|
|
* @param $objectOrClass |
18
|
|
|
* @param array|null $map fieldName: propertyName |
19
|
|
|
* |
20
|
|
|
* @return object |
21
|
|
|
* @throws \ReflectionException |
22
|
|
|
*/ |
23
|
|
|
public function hydrate(array $data, $objectOrClass, array $map = null) |
24
|
|
|
{ |
25
|
|
|
if (\is_object($objectOrClass)) { |
26
|
|
|
$object = $objectOrClass; |
27
|
|
|
$reflection = $this->getReflection(\get_class($object)); |
28
|
|
|
} else { |
29
|
|
|
$reflection = $this->getReflection($objectOrClass); |
30
|
|
|
$object = $reflection->newInstanceWithoutConstructor(); |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
if (!\is_array($map) || !$map) { |
|
|
|
|
34
|
|
|
$map = \array_keys($data); |
35
|
|
|
$map = \array_combine($map, $map); |
36
|
|
|
} |
37
|
|
|
foreach ($map as $fieldName => $propertyName) { |
38
|
|
|
if (isset($data[$fieldName]) && $reflection->hasProperty($propertyName)) { |
39
|
|
|
$property = $this->getProperty($reflection, $propertyName); |
40
|
|
|
$property->setValue($object, $data[$fieldName]); |
41
|
|
|
} |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
return $object; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* extract object properties to data |
49
|
|
|
* |
50
|
|
|
* @param object $object |
51
|
|
|
* @param array $map fieldName: propertyName |
52
|
|
|
* |
53
|
|
|
* @return array |
54
|
|
|
* @throws \ReflectionException |
55
|
|
|
*/ |
56
|
|
|
public function extract($object, array $map = null): array |
57
|
|
|
{ |
58
|
|
|
$result = []; |
59
|
|
|
|
60
|
|
|
$className = \get_class($object); |
61
|
|
|
$reflection = $this->getReflection($className); |
62
|
|
|
|
63
|
|
|
if (!\is_array($map) || !$map) { |
|
|
|
|
64
|
|
|
$propertyList = $this->getReflectionPropertyList($className); |
65
|
|
|
$map = \array_combine($propertyList, $propertyList); |
66
|
|
|
} |
67
|
|
|
foreach ($map as $fieldName => $propertyName) { |
68
|
|
|
if ($reflection->hasProperty($propertyName)) { |
69
|
|
|
$property = $this->getProperty($reflection, $propertyName); |
70
|
|
|
$result[$fieldName] = $property->getValue($object); |
71
|
|
|
} |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
return $result; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* @param $className |
79
|
|
|
* @return \ReflectionClass |
80
|
|
|
* @throws \ReflectionException |
81
|
|
|
*/ |
82
|
|
|
protected function getReflection($className): \ReflectionClass |
83
|
|
|
{ |
84
|
|
|
if (!isset($this->reflections[$className])) { |
85
|
|
|
$this->reflections[$className] = new \ReflectionClass($className); |
86
|
|
|
} |
87
|
|
|
return $this->reflections[$className]; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* @param $className |
92
|
|
|
* @return array |
93
|
|
|
* @throws \ReflectionException |
94
|
|
|
*/ |
95
|
|
|
protected function getReflectionPropertyList($className): array |
96
|
|
|
{ |
97
|
|
|
if (!isset($this->reflectionsPropertyList[$className])) { |
98
|
|
|
$this->reflectionsPropertyList[$className] = []; |
99
|
|
|
foreach ($this->getReflection($className)->getProperties() as $property) { |
100
|
|
|
$this->reflectionsPropertyList[$className][] = $property->getName(); |
101
|
|
|
} |
102
|
|
|
} |
103
|
|
|
return $this->reflectionsPropertyList[$className]; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* @param \ReflectionClass $reflection |
108
|
|
|
* @param $propertyName |
109
|
|
|
* |
110
|
|
|
* @return ReflectionProperty |
111
|
|
|
*/ |
112
|
|
|
protected function getProperty(\ReflectionClass $reflection, $propertyName): ReflectionProperty |
113
|
|
|
{ |
114
|
|
|
$property = $reflection->getProperty($propertyName); |
115
|
|
|
$property->setAccessible(true); |
116
|
|
|
return $property; |
117
|
|
|
} |
118
|
|
|
} |
119
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.