Hydrator::extract()   B
last analyzed

Complexity

Conditions 5
Paths 6

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 11
nc 6
nop 2
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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $map of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $map of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
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