Completed
Branch master (2d39e9)
by Rémi
11:28
created

Wrapper::getClassToProxy()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Analogue\ORM\System\Wrappers;
4
5
use Analogue\ORM\System\InternallyMappable;
6
use Analogue\ORM\System\Proxies\ProxyFactory;
7
8
/**
9
 * The Wrapper Class provides a single interface access several Entity types.
10
 */
11
abstract class Wrapper implements InternallyMappable
12
{
13
    /**
14
     * Original Entity Object.
15
     *
16
     * @var mixed
17
     */
18
    protected $entity;
19
20
    /**
21
     * Corresponding EntityMap.
22
     *
23
     * @var \Analogue\ORM\EntityMap
24
     */
25
    protected $entityMap;
26
27
    /**
28
     * @var \Analogue\ORM\System\Proxirs\ProxyFactory
29
     */
30
    protected $proxyFactory;
31
32
    /**
33
     * Wrapper constructor.
34
     *
35
     * @param $entity
36
     * @param $entityMap
37
     */
38
    public function __construct($entity, $entityMap)
39
    {
40
        $this->entity = $entity;
41
        $this->entityMap = $entityMap;
42
        $this->proxyFactory = new ProxyFactory();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Analogue\ORM\System\Proxies\ProxyFactory() of type object<Analogue\ORM\System\Proxies\ProxyFactory> is incompatible with the declared type object<Analogue\ORM\System\Proxirs\ProxyFactory> of property $proxyFactory.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
43
    }
44
45
    /**
46
     * Return the wrapped entity class.
47
     *
48
     * @return mixed
49
     */
50
    public function getEntityClass()
51
    {
52
        return get_class($this->entity);
53
    }
54
55
    /**
56
     * Return the entity's primary key valuye.
57
     *
58
     * @return string
59
     */
60
    public function getEntityKey()
61
    {
62
        return $this->getEntityAttribute($this->entityMap->getKeyName());
63
    }
64
65
    /**
66
     * Return the Entity class/primary key couple,
67
     * which is used for internall operations.
68
     *
69
     * @return string
70
     */
71
    public function getEntityHash()
72
    {
73
        return $this->getEntityClass().'.'.$this->getEntityKey();
74
    }
75
76
    /**
77
     * Returns the wrapped entity.
78
     *
79
     * @return mixed
80
     */
81
    public function getObject()
82
    {
83
        return $this->entity;
84
    }
85
86
    /**
87
     * Returns the wrapped entity's map.
88
     *
89
     * @return mixed
90
     */
91
    public function getMap()
92
    {
93
        return $this->entityMap;
94
    }
95
96
    /**
97
     * Set the lazyloading proxies on the wrapped entity objet.
98
     *
99
     * @param array $relations list of relations to be lazy loaded
100
     *
101
     * @return void
102
     */
103
    public function setProxies(array $relations = null)
104
    {
105
        $attributes = $this->getEntityAttributes();
106
        $proxies = [];
107
108
        if (is_null($relations)) {
109
            $relations = $this->getRelationsToProxy();
110
        }
111
112
        foreach ($relations as $relation) {
113
            // We first look if we need to build the proxy on the relationship.
114
            // If the key is handled locally and we know it not to be set,
115
            // we'll set the relationship to null
116
            if (!$this->relationNeedsProxy($relation, $attributes)) {
117
                $proxies[$relation] = null;
118
            } else {
119
                $targetClass = $this->getClassToProxy($relation, $attributes);
120
                $proxies[$relation] = $this->proxyFactory->make($this->getObject(), $relation, $targetClass);
121
            }
122
        }
123
124
        foreach ($proxies as $key => $value) {
125
            $this->setEntityAttribute($key, $value);
126
        }
127
    }
128
129
    /**
130
     * Get Target class to proxy for a one to one.
131
     *
132
     * @param string $relation
133
     * @param array  $attributes
134
     *
135
     * @return string
136
     */
137
    protected function getClassToProxy($relation, array $attributes)
138
    {
139
        if ($this->entityMap->isPolymorphic($relation)) {
140
            $localTypeAttribute = $this->entityMap->getLocalKeys($relation)['type'];
141
142
            return $attributes[$localTypeAttribute];
143
        }
144
145
        return $this->entityMap->getTargettedClass($relation);
146
    }
147
148
    /**
149
     * Determine which relations we have to build proxy for, by parsing
150
     * attributes and finding methods that aren't set.
151
     *
152
     * @return array
153
     */
154
    protected function getRelationsToProxy()
155
    {
156
        $proxies = [];
157
        $attributes = $this->getEntityAttributes();
158
159
        foreach ($this->entityMap->getRelationships() as $relation) {
160
            if (!array_key_exists($relation, $attributes)) {
161
                $proxies[] = $relation;
162
            }
163
        }
164
165
        return $proxies;
166
    }
167
168
    /**
169
     * Determine if the relation needs a proxy or not.
170
     *
171
     * @param string $relation
172
     * @param array  $attributes
173
     *
174
     * @return bool
175
     */
176
    protected function relationNeedsProxy($relation, $attributes)
177
    {
178
        if (in_array($relation, $this->entityMap->getRelationshipsWithoutProxy())) {
179
            return false;
180
        }
181
182
        $localKey = $this->entityMap->getLocalKeys($relation);
183
184
        if (is_null($localKey)) {
185
            return true;
186
        }
187
188
        if (is_array($localKey)) {
189
            $localKey = $localKey['id'];
190
        }
191
192
        if (!isset($attributes[$localKey])) {
193
            return false;
194
        }
195
196
        if (is_null($attributes[$localKey])) {
197
            return false;
198
        }
199
200
        return true;
201
    }
202
203
    /**
204
     * @param string $key
205
     * @param string $value
206
     *
207
     * @return mixed
208
     */
209
    abstract public function setEntityAttribute($key, $value);
210
211
    /**
212
     * @param string $key
213
     *
214
     * @return mixed
215
     */
216
    abstract public function getEntityAttribute($key);
217
218
    /**
219
     * @param array $attributes
220
     *
221
     * @return mixed
222
     */
223
    abstract public function setEntityAttributes(array $attributes);
224
225
    /**
226
     * @return mixed
227
     */
228
    abstract public function getEntityAttributes();
229
230
    /**
231
     * @param string $key
232
     *
233
     * @return mixed
234
     */
235
    abstract public function hasAttribute($key);
236
}
237