Completed
Branch master (411345)
by Rémi
11:20
created

EntityBuilder::getLazyLoadingProxies()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 5
nop 1
dl 0
loc 22
rs 8.9197
c 0
b 0
f 0
1
<?php
2
3
namespace Analogue\ORM\System;
4
5
use Analogue\ORM\System\Wrappers\Factory;
6
7
/**
8
 * This class builds an array of Entity object(s) from a result set.
9
 */
10
class EntityBuilder
11
{
12
    /**
13
     * The mapper for the entity to build
14
     * @var \Analogue\ORM\System\Mapper
15
     */
16
    protected $mapper;
17
18
    /**
19
     * The Entity Map for the entity to build.
20
     *
21
     * @var \Analogue\ORM\EntityMap
22
     */
23
    protected $entityMap;
24
25
    /**
26
     * Relations that are eager loaded on this query
27
     *
28
     * @var array
29
     */
30
    protected $eagerLoads;
31
32
    /**
33
     * Relations that will be lazy loaded on this query
34
     *
35
     * @var array
36
     */
37
    protected $lazyLoads;
38
39
    /**
40
     * @var array
41
     */
42
    protected $casts;
43
44
    /**
45
     * Entity Wrapper Factory
46
     * @var \Analogue\ORM\System\Wrappers\Factory
47
     */
48
    protected $factory;
49
50
    /**
51
     * EntityBuilder constructor.
52
     * 
53
     * @param Mapper $mapper
54
     * @param array  $eagerLoads
55
     */
56
    public function __construct(Mapper $mapper, array $eagerLoads)
57
    {
58
        $this->mapper = $mapper;
59
60
        $this->entityMap = $mapper->getEntityMap();
61
62
        $this->eagerLoads = $eagerLoads;
63
64
        $this->lazyLoads = $this->getRelationshipsToProxy();
65
66
        $this->factory = new Factory;
67
    }
68
69
    /**
70
     * Convert an array of values into an entity.
71
     *
72
     * @param  array $result
73
     * @return array
74
     */
75
    public function build(array $result)
76
    {
77
        $instance = $this->getWrapperInstance();
78
        
79
        // Hydrate any embedded Value Object
80
        // 
81
        // TODO Move this to the result builder instead,
82
        // as we'll handle this the same way as they were
83
        // eager loaded relationships. 
84
        $this->hydrateValueObjects($result);
85
86
        $instance->setEntityAttributes($result);
87
88
        // Hydrate relationship attributes with lazyloading proxies
89
        if (count($this->lazyLoads) > 0) {
90
            $instance->setProxies($this->lazyLoads);
91
        }
92
93
        // Hydrate and return the instance
94
        $instance->hydrate();
95
        $entity = $instance->getObject();
96
97
        return $entity;
98
    }
99
100
    /**
101
     * Get the correct wrapper prototype corresponding to the object type
102
     *
103
     * @throws \Analogue\ORM\Exceptions\MappingException
104
     * @return InternallyMappable
105
     */
106
    protected function getWrapperInstance()
107
    {
108
        return $this->factory->make($this->mapper->newInstance());
109
    }
110
111
    /**
112
     * Hydrate value object embedded in this entity
113
     *
114
     * @param  array $attributes
115
     * @throws \Analogue\ORM\Exceptions\MappingException
116
     * @return void
117
     */
118
    protected function hydrateValueObjects(& $attributes)
119
    {
120
        foreach ($this->entityMap->getEmbeddables() as $localKey => $valueClass) {
121
            $this->hydrateValueObject($attributes, $localKey, $valueClass);
122
        }
123
    }
124
125
    /**
126
     * Hydrate a single value object
127
     *
128
     * @param  array  $attributes
129
     * @param  string $localKey
130
     * @param  string $valueClass
131
     * @throws \Analogue\ORM\Exceptions\MappingException
132
     * @return void
133
     */
134
    protected function hydrateValueObject(& $attributes, $localKey, $valueClass)
135
    {
136
        $map = $this->mapper->getManager()->getValueMap($valueClass);
137
138
        $embeddedAttributes = $map->getAttributes();
139
140
        $valueObject = $this->mapper->getManager()->getValueObjectInstance($valueClass);
141
        $voWrapper = $this->factory->make($valueObject);
142
143
        foreach ($embeddedAttributes as $key) {
144
145
            $prefix = snake_case(class_basename($valueClass)) . '_';
146
147
            $voWrapper->setEntityAttribute($key, $attributes[$prefix . $key]);
148
149
            unset($attributes[$prefix . $key]);
150
        }
151
152
        $attributes[$localKey] = $voWrapper->getObject();
153
    }
154
155
    /**
156
     * Deduce the relationships for which we will build lazy loading proxies
157
     *
158
     * @return array
159
     */
160
    protected function getRelationshipsToProxy()
161
    {
162
        $relations = $this->entityMap->getRelationships();
163
164
        return array_diff($relations, $this->eagerLoads);
165
    }
166
167
}