Completed
Branch master (411345)
by Rémi
11:20
created
src/Relationships/HasMany.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -11,7 +11,7 @@  discard block
 block discarded – undo
11 11
      *
12 12
      * @param  $relation
13 13
      *
14
-     * @return mixed
14
+     * @return EntityCollection
15 15
      */
16 16
     public function getResults($relation)
17 17
     {
@@ -25,7 +25,7 @@  discard block
 block discarded – undo
25 25
     /**
26 26
      * Match the eagerly loaded results to their parents.
27 27
      *
28
-     * @param  array             $$results
28
+     * @param  array             $results
29 29
      * @param  string            $relation
30 30
      * @return array
31 31
      */
Please login to merge, or discard this patch.
Unused Use Statements   -2 removed lines patch added patch discarded remove patch
@@ -2,8 +2,6 @@
 block discarded – undo
2 2
 
3 3
 namespace Analogue\ORM\Relationships;
4 4
 
5
-use Analogue\ORM\EntityCollection;
6
-
7 5
 class HasMany extends HasOneOrMany
8 6
 {
9 7
     /**
Please login to merge, or discard this patch.
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -6,31 +6,31 @@
 block discarded – undo
6 6
 
7 7
 class HasMany extends HasOneOrMany
8 8
 {
9
-    /**
10
-     * Lazy-Load the results of the relationship
11
-     *
12
-     * @param  $relation
13
-     *
14
-     * @return mixed
15
-     */
16
-    public function getResults($relation)
17
-    {
18
-        $results = $this->query->get();
9
+	/**
10
+	 * Lazy-Load the results of the relationship
11
+	 *
12
+	 * @param  $relation
13
+	 *
14
+	 * @return mixed
15
+	 */
16
+	public function getResults($relation)
17
+	{
18
+		$results = $this->query->get();
19 19
 
20
-        $this->cacheRelation($results, $relation);
20
+		$this->cacheRelation($results, $relation);
21 21
 
22
-        return $results;
23
-    }
22
+		return $results;
23
+	}
24 24
 
25
-    /**
26
-     * Match the eagerly loaded results to their parents.
27
-     *
28
-     * @param  array             $$results
29
-     * @param  string            $relation
30
-     * @return array
31
-     */
32
-    public function match(array $results, $relation)
33
-    {
34
-        return $this->matchMany($results, $relation);
35
-    }
25
+	/**
26
+	 * Match the eagerly loaded results to their parents.
27
+	 *
28
+	 * @param  array             $$results
29
+	 * @param  string            $relation
30
+	 * @return array
31
+	 */
32
+	public function match(array $results, $relation)
33
+	{
34
+		return $this->matchMany($results, $relation);
35
+	}
36 36
 }
Please login to merge, or discard this patch.
src/System/EntityCache.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -188,7 +188,7 @@  discard block
 block discarded – undo
188 188
     /**
189 189
      * Cache a many relationship
190 190
      *
191
-     * @param                  $parentKey
191
+     * @param                  string $parentKey
192 192
      * @param string           $relation
193 193
      * @param EntityCollection $results
194 194
      * @param Relationship     $relationship
@@ -210,7 +210,7 @@  discard block
 block discarded – undo
210 210
     /**
211 211
      * Cache a single relationship
212 212
      *
213
-     * @param              $parentKey
213
+     * @param              string $parentKey
214 214
      * @param string       $relation
215 215
      * @param Mappable     $result
216 216
      * @param Relationship $relationship
Please login to merge, or discard this patch.
Indentation   +319 added lines, -319 removed lines patch added patch discarded remove patch
@@ -15,324 +15,324 @@
 block discarded – undo
15 15
  */
16 16
 class EntityCache
17 17
 {
18
-    /**
19
-     * Entity's raw attributes/relationships
20
-     *
21
-     * @var array
22
-     */
23
-    protected $cache = [];
24
-
25
-    /**
26
-     * Entity Map for the current Entity Type
27
-     * @var \Analogue\ORM\EntityMap
28
-     */
29
-    protected $entityMap;
30
-
31
-    /**
32
-     * Wrapper factory
33
-     *
34
-     * @var \Analogue\ORM\System\Wrappers\Factory
35
-     */
36
-    protected $factory;
37
-
38
-    /**
39
-     * Associative array containing list of pivot attributes per relationship
40
-     * so we don't have to call relationship method on refresh.
41
-     *
42
-     * @var array
43
-     */
44
-    protected $pivotAttributes = [];
45
-
46
-    /**
47
-     * EntityCache constructor.
48
-     * @param EntityMap $entityMap
49
-     */
50
-    public function __construct(EntityMap $entityMap)
51
-    {
52
-        $this->entityMap = $entityMap;
53
-
54
-        $this->factory = new Factory;
55
-    }
56
-
57
-    /**
58
-     * Add an array of key=>attributes representing
59
-     * the initial state of loaded entities.
60
-     *
61
-     * @param array $results
62
-     */
63
-    public function add(array $results)
64
-    {
65
-        $cachedResults = [];
66
-
67
-        $keyColumn = $this->entityMap->getKeyName();
68
-
69
-        foreach($results as $result) {
70
-            $id = $result[$keyColumn];
71
-
72
-            // Forget the ID field from the cache attributes
73
-            // to prevent any side effect.
74
-            unset($result[$keyColumn]);
75
-            $cachedResults[$id] = $result;
76
-        }
77
-
78
-        if (count($this->cache) == 0) {
79
-            $this->cache = $cachedResults;
80
-        } else {
81
-            $this->mergeCacheResults($cachedResults);
82
-        }
83
-    }
84
-
85
-    /**
86
-     * Retrieve initial attributes for a single entity
87
-     *
88
-     * @param  string $id
89
-     * @return array
90
-     */
91
-    public function get($id)
92
-    {
93
-        if ($this->has($id)) {
94
-            return $this->cache[$id];
95
-        } else {
96
-            return [];
97
-        }
98
-    }
99
-
100
-    /**
101
-     * Check if a record for this id exists.
102
-     *
103
-     * @param  string  $id
104
-     * @return boolean
105
-     */
106
-    public function has($id)
107
-    {
108
-        return array_key_exists($id, $this->cache);
109
-    }
110
-
111
-    /**
112
-     * Combine new result set with existing attributes in
113
-     * cache.
114
-     *
115
-     * @param  array $entities
116
-     * @return void
117
-     */
118
-    protected function mergeCacheResults($entities)
119
-    {
120
-        foreach ($entities as $key => $entity) {
121
-            $this->cache[$key] = $entity;
122
-        }
123
-    }
124
-
125
-    /**
126
-     * Cache Relation's query result for an entity
127
-     *
128
-     * @param  string       $key  primary key of the cached entity
129
-     * @param  string       $relation name of the relation
130
-     * @param  mixed        $results  results of the relationship's query
131
-     * @param  Relationship $relationship
132
-     * @throws MappingException
133
-     * @return void
134
-     */
135
-    public function cacheLoadedRelationResult($key, $relation, $results, Relationship $relationship)
136
-    {   
137
-        if ($results instanceof EntityCollection) {
138
-            $this->cacheManyRelationResults($key, $relation, $results, $relationship);
139
-        }
140
-
141
-        // TODO : As we support popo Entities, Maybe this check isn't needed anymore, 
142
-        // or we have to check that $result is an object instead
143
-        if ($results instanceof Mappable) {
144
-            $this->cacheSingleRelationResult($key, $relation, $results, $relationship);
145
-        }
146
-    }
147
-
148
-    /**
149
-     * Create a cachedRelationship instance which will hold related entity's hash and pivot attributes, if any.
150
-     *
151
-     * @param  string       $parentKey
152
-     * @param  string       $relation
153
-     * @param  array        $result
154
-     * @param  Relationship $relationship
155
-     * @throws MappingException
156
-     * @return CachedRelationship
157
-     */
158
-    protected function getCachedRelationship($parentKey, $relation, $result, Relationship $relationship)
159
-    {
160
-        $pivotColumns = $relationship->getPivotAttributes();
161
-
162
-        if (!array_key_exists($relation, $this->pivotAttributes)) {
163
-            $this->pivotAttributes[$relation] = $pivotColumns;
164
-        }
165
-
166
-        $wrapper = $this->factory->make($result);
167
-
168
-        $hash = $wrapper->getEntityHash();
169
-
170
-        if (count($pivotColumns) > 0) {
171
-            $pivotAttributes = [];
172
-            foreach ($pivotColumns as $column) {
173
-                $pivot = $wrapper->getEntityAttribute('pivot');
174
-
175
-                $pivotWrapper = $this->factory->make($pivot);
176
-
177
-                $pivotAttributes[$column] = $pivotWrapper->getEntityAttribute($column);
178
-            }
179
-
180
-            $cachedRelationship = new CachedRelationship($hash, $pivotAttributes);
181
-        } else {
182
-            $cachedRelationship = new CachedRelationship($hash);
183
-        }
184
-
185
-        return $cachedRelationship;
186
-    }
187
-
188
-    /**
189
-     * Cache a many relationship
190
-     *
191
-     * @param                  $parentKey
192
-     * @param string           $relation
193
-     * @param EntityCollection $results
194
-     * @param Relationship     $relationship
195
-     * @throws MappingException
196
-     */
197
-    protected function cacheManyRelationResults($parentKey, $relation, $results, Relationship $relationship)
198
-    {
199
-        $this->cache[$parentKey][$relation] = [];
200
-
201
-        foreach ($results as $result) {
202
-            $cachedRelationship = $this->getCachedRelationship($parentKey, $relation, $result, $relationship);
203
-
204
-            $relatedHash = $cachedRelationship->getHash();
205
-
206
-            $this->cache[$parentKey][$relation][$relatedHash] = $cachedRelationship;
207
-        }
208
-    }
209
-
210
-    /**
211
-     * Cache a single relationship
212
-     *
213
-     * @param              $parentKey
214
-     * @param string       $relation
215
-     * @param Mappable     $result
216
-     * @param Relationship $relationship
217
-     * @throws MappingException
218
-     */
219
-    protected function cacheSingleRelationResult($parentKey, $relation, $result, Relationship $relationship)
220
-    {
221
-        $this->cache[$parentKey][$relation] = $this->getCachedRelationship($parentKey, $relation, $result, $relationship);
222
-    }
223
-
224
-    /**
225
-     * Get Entity's Hash
226
-     *
227
-     * @param  $entity
228
-     * @throws MappingException
229
-     * @return string
230
-     */
231
-    protected function getEntityHash(InternallyMappable $entity)
232
-    {
233
-        $class = $entity->getEntityClass();
234
-
235
-        $mapper = Manager::getMapper($class);
236
-
237
-        $keyName = $mapper->getEntityMap()->getKeyName();
238
-
239
-        return $class . '.' . $entity->getEntityAttribute($keyName);
240
-    }
241
-
242
-    /**
243
-     * Refresh the cache record for an aggregated entity after a write operation
244
-     * @param Aggregate $entity
245
-     */
246
-    public function refresh(Aggregate $entity)
247
-    {
248
-        $this->cache[$entity->getEntityId()] = $this->transform($entity);
249
-    }
250
-
251
-    /**
252
-     * Transform an Aggregated Entity into a cache record
253
-     *
254
-     * @param  Aggregate $aggregatedEntity
255
-     * @throws MappingException
256
-     * @return array
257
-     */
258
-    protected function transform(Aggregate $aggregatedEntity)
259
-    {
260
-        $baseAttributes = $aggregatedEntity->getRawAttributes();
261
-
262
-        $relationAttributes = [];
263
-
264
-        // First we'll handle each relationships that are a one to one
265
-        // relation, and which will be saved as a CachedRelationship
266
-        // object inside the cache.
267
-
268
-        // NOTE : storing localRelationships maybe useless has we store
269
-        // the foreign key in the attributes already.
270
-
271
-        foreach ($this->entityMap->getSingleRelationships() as $relation) {
272
-            $aggregates = $aggregatedEntity->getRelationship($relation);
18
+	/**
19
+	 * Entity's raw attributes/relationships
20
+	 *
21
+	 * @var array
22
+	 */
23
+	protected $cache = [];
24
+
25
+	/**
26
+	 * Entity Map for the current Entity Type
27
+	 * @var \Analogue\ORM\EntityMap
28
+	 */
29
+	protected $entityMap;
30
+
31
+	/**
32
+	 * Wrapper factory
33
+	 *
34
+	 * @var \Analogue\ORM\System\Wrappers\Factory
35
+	 */
36
+	protected $factory;
37
+
38
+	/**
39
+	 * Associative array containing list of pivot attributes per relationship
40
+	 * so we don't have to call relationship method on refresh.
41
+	 *
42
+	 * @var array
43
+	 */
44
+	protected $pivotAttributes = [];
45
+
46
+	/**
47
+	 * EntityCache constructor.
48
+	 * @param EntityMap $entityMap
49
+	 */
50
+	public function __construct(EntityMap $entityMap)
51
+	{
52
+		$this->entityMap = $entityMap;
53
+
54
+		$this->factory = new Factory;
55
+	}
56
+
57
+	/**
58
+	 * Add an array of key=>attributes representing
59
+	 * the initial state of loaded entities.
60
+	 *
61
+	 * @param array $results
62
+	 */
63
+	public function add(array $results)
64
+	{
65
+		$cachedResults = [];
66
+
67
+		$keyColumn = $this->entityMap->getKeyName();
68
+
69
+		foreach($results as $result) {
70
+			$id = $result[$keyColumn];
71
+
72
+			// Forget the ID field from the cache attributes
73
+			// to prevent any side effect.
74
+			unset($result[$keyColumn]);
75
+			$cachedResults[$id] = $result;
76
+		}
77
+
78
+		if (count($this->cache) == 0) {
79
+			$this->cache = $cachedResults;
80
+		} else {
81
+			$this->mergeCacheResults($cachedResults);
82
+		}
83
+	}
84
+
85
+	/**
86
+	 * Retrieve initial attributes for a single entity
87
+	 *
88
+	 * @param  string $id
89
+	 * @return array
90
+	 */
91
+	public function get($id)
92
+	{
93
+		if ($this->has($id)) {
94
+			return $this->cache[$id];
95
+		} else {
96
+			return [];
97
+		}
98
+	}
99
+
100
+	/**
101
+	 * Check if a record for this id exists.
102
+	 *
103
+	 * @param  string  $id
104
+	 * @return boolean
105
+	 */
106
+	public function has($id)
107
+	{
108
+		return array_key_exists($id, $this->cache);
109
+	}
110
+
111
+	/**
112
+	 * Combine new result set with existing attributes in
113
+	 * cache.
114
+	 *
115
+	 * @param  array $entities
116
+	 * @return void
117
+	 */
118
+	protected function mergeCacheResults($entities)
119
+	{
120
+		foreach ($entities as $key => $entity) {
121
+			$this->cache[$key] = $entity;
122
+		}
123
+	}
124
+
125
+	/**
126
+	 * Cache Relation's query result for an entity
127
+	 *
128
+	 * @param  string       $key  primary key of the cached entity
129
+	 * @param  string       $relation name of the relation
130
+	 * @param  mixed        $results  results of the relationship's query
131
+	 * @param  Relationship $relationship
132
+	 * @throws MappingException
133
+	 * @return void
134
+	 */
135
+	public function cacheLoadedRelationResult($key, $relation, $results, Relationship $relationship)
136
+	{   
137
+		if ($results instanceof EntityCollection) {
138
+			$this->cacheManyRelationResults($key, $relation, $results, $relationship);
139
+		}
140
+
141
+		// TODO : As we support popo Entities, Maybe this check isn't needed anymore, 
142
+		// or we have to check that $result is an object instead
143
+		if ($results instanceof Mappable) {
144
+			$this->cacheSingleRelationResult($key, $relation, $results, $relationship);
145
+		}
146
+	}
147
+
148
+	/**
149
+	 * Create a cachedRelationship instance which will hold related entity's hash and pivot attributes, if any.
150
+	 *
151
+	 * @param  string       $parentKey
152
+	 * @param  string       $relation
153
+	 * @param  array        $result
154
+	 * @param  Relationship $relationship
155
+	 * @throws MappingException
156
+	 * @return CachedRelationship
157
+	 */
158
+	protected function getCachedRelationship($parentKey, $relation, $result, Relationship $relationship)
159
+	{
160
+		$pivotColumns = $relationship->getPivotAttributes();
161
+
162
+		if (!array_key_exists($relation, $this->pivotAttributes)) {
163
+			$this->pivotAttributes[$relation] = $pivotColumns;
164
+		}
165
+
166
+		$wrapper = $this->factory->make($result);
167
+
168
+		$hash = $wrapper->getEntityHash();
169
+
170
+		if (count($pivotColumns) > 0) {
171
+			$pivotAttributes = [];
172
+			foreach ($pivotColumns as $column) {
173
+				$pivot = $wrapper->getEntityAttribute('pivot');
174
+
175
+				$pivotWrapper = $this->factory->make($pivot);
176
+
177
+				$pivotAttributes[$column] = $pivotWrapper->getEntityAttribute($column);
178
+			}
179
+
180
+			$cachedRelationship = new CachedRelationship($hash, $pivotAttributes);
181
+		} else {
182
+			$cachedRelationship = new CachedRelationship($hash);
183
+		}
184
+
185
+		return $cachedRelationship;
186
+	}
187
+
188
+	/**
189
+	 * Cache a many relationship
190
+	 *
191
+	 * @param                  $parentKey
192
+	 * @param string           $relation
193
+	 * @param EntityCollection $results
194
+	 * @param Relationship     $relationship
195
+	 * @throws MappingException
196
+	 */
197
+	protected function cacheManyRelationResults($parentKey, $relation, $results, Relationship $relationship)
198
+	{
199
+		$this->cache[$parentKey][$relation] = [];
200
+
201
+		foreach ($results as $result) {
202
+			$cachedRelationship = $this->getCachedRelationship($parentKey, $relation, $result, $relationship);
203
+
204
+			$relatedHash = $cachedRelationship->getHash();
205
+
206
+			$this->cache[$parentKey][$relation][$relatedHash] = $cachedRelationship;
207
+		}
208
+	}
209
+
210
+	/**
211
+	 * Cache a single relationship
212
+	 *
213
+	 * @param              $parentKey
214
+	 * @param string       $relation
215
+	 * @param Mappable     $result
216
+	 * @param Relationship $relationship
217
+	 * @throws MappingException
218
+	 */
219
+	protected function cacheSingleRelationResult($parentKey, $relation, $result, Relationship $relationship)
220
+	{
221
+		$this->cache[$parentKey][$relation] = $this->getCachedRelationship($parentKey, $relation, $result, $relationship);
222
+	}
223
+
224
+	/**
225
+	 * Get Entity's Hash
226
+	 *
227
+	 * @param  $entity
228
+	 * @throws MappingException
229
+	 * @return string
230
+	 */
231
+	protected function getEntityHash(InternallyMappable $entity)
232
+	{
233
+		$class = $entity->getEntityClass();
234
+
235
+		$mapper = Manager::getMapper($class);
236
+
237
+		$keyName = $mapper->getEntityMap()->getKeyName();
238
+
239
+		return $class . '.' . $entity->getEntityAttribute($keyName);
240
+	}
241
+
242
+	/**
243
+	 * Refresh the cache record for an aggregated entity after a write operation
244
+	 * @param Aggregate $entity
245
+	 */
246
+	public function refresh(Aggregate $entity)
247
+	{
248
+		$this->cache[$entity->getEntityId()] = $this->transform($entity);
249
+	}
250
+
251
+	/**
252
+	 * Transform an Aggregated Entity into a cache record
253
+	 *
254
+	 * @param  Aggregate $aggregatedEntity
255
+	 * @throws MappingException
256
+	 * @return array
257
+	 */
258
+	protected function transform(Aggregate $aggregatedEntity)
259
+	{
260
+		$baseAttributes = $aggregatedEntity->getRawAttributes();
261
+
262
+		$relationAttributes = [];
263
+
264
+		// First we'll handle each relationships that are a one to one
265
+		// relation, and which will be saved as a CachedRelationship
266
+		// object inside the cache.
267
+
268
+		// NOTE : storing localRelationships maybe useless has we store
269
+		// the foreign key in the attributes already.
270
+
271
+		foreach ($this->entityMap->getSingleRelationships() as $relation) {
272
+			$aggregates = $aggregatedEntity->getRelationship($relation);
273 273
             
274
-            if (count($aggregates) == 1) {
275
-                $related = $aggregates[0];
276
-                $relationAttributes[$relation] = new CachedRelationship($related->getEntityHash());
277
-            }
278
-            if (count($aggregates) > 1) {
279
-                throw new MappingException("Single Relationship '$relation' contains several related entities");
280
-            }
281
-        }
282
-
283
-        // Then we'll handle the 'many' relationships and store them as
284
-        // an array of CachedRelationship objects.
285
-
286
-        foreach ($this->entityMap->getManyRelationships() as $relation) {
287
-            $aggregates = $aggregatedEntity->getRelationship($relation);
288
-
289
-            $relationAttributes[$relation] = [];
290
-
291
-            foreach ($aggregates as $aggregate) {
292
-                $relationAttributes[$relation][] = new CachedRelationship(
293
-                    $aggregate->getEntityHash(),
294
-                    $aggregate->getPivotAttributes()
295
-                );
296
-            }
297
-        }
298
-
299
-        return $baseAttributes + $relationAttributes;
300
-    }
301
-
302
-    /**
303
-     * Get pivot attributes for a relation
304
-     * 
305
-     * @param  string             $relation
306
-     * @param  InternallyMappable $entity
307
-     * @return array
308
-     */
309
-    protected function getPivotValues($relation, InternallyMappable $entity)
310
-    {
311
-        $values = [];
312
-
313
-        $entityAttributes = $entity->getEntityAttributes();
314
-
315
-        if (array_key_exists($relation, $this->pivotAttributes)) {
316
-            foreach ($this->pivotAttributes[$relation] as $attribute) {
317
-                if (array_key_exists($attribute, $entityAttributes)) {
318
-                    $values[$attribute] = $entity->getEntityAttribute('pivot')->$attribute;
319
-                }
320
-            }
321
-        }
322
-
323
-        return $values;
324
-    }
325
-
326
-    /**
327
-     * Clear the entity Cache. Use with caution as it could result
328
-     * in impredictable behaviour if the cached entities are stored
329
-     * after the cache clear operation. 
330
-     * 
331
-     * @return void
332
-     */
333
-    public function clear()
334
-    {   
335
-        $this->cache = [];
336
-        $this->pivotAttributes = [];
337
-    }
274
+			if (count($aggregates) == 1) {
275
+				$related = $aggregates[0];
276
+				$relationAttributes[$relation] = new CachedRelationship($related->getEntityHash());
277
+			}
278
+			if (count($aggregates) > 1) {
279
+				throw new MappingException("Single Relationship '$relation' contains several related entities");
280
+			}
281
+		}
282
+
283
+		// Then we'll handle the 'many' relationships and store them as
284
+		// an array of CachedRelationship objects.
285
+
286
+		foreach ($this->entityMap->getManyRelationships() as $relation) {
287
+			$aggregates = $aggregatedEntity->getRelationship($relation);
288
+
289
+			$relationAttributes[$relation] = [];
290
+
291
+			foreach ($aggregates as $aggregate) {
292
+				$relationAttributes[$relation][] = new CachedRelationship(
293
+					$aggregate->getEntityHash(),
294
+					$aggregate->getPivotAttributes()
295
+				);
296
+			}
297
+		}
298
+
299
+		return $baseAttributes + $relationAttributes;
300
+	}
301
+
302
+	/**
303
+	 * Get pivot attributes for a relation
304
+	 * 
305
+	 * @param  string             $relation
306
+	 * @param  InternallyMappable $entity
307
+	 * @return array
308
+	 */
309
+	protected function getPivotValues($relation, InternallyMappable $entity)
310
+	{
311
+		$values = [];
312
+
313
+		$entityAttributes = $entity->getEntityAttributes();
314
+
315
+		if (array_key_exists($relation, $this->pivotAttributes)) {
316
+			foreach ($this->pivotAttributes[$relation] as $attribute) {
317
+				if (array_key_exists($attribute, $entityAttributes)) {
318
+					$values[$attribute] = $entity->getEntityAttribute('pivot')->$attribute;
319
+				}
320
+			}
321
+		}
322
+
323
+		return $values;
324
+	}
325
+
326
+	/**
327
+	 * Clear the entity Cache. Use with caution as it could result
328
+	 * in impredictable behaviour if the cached entities are stored
329
+	 * after the cache clear operation. 
330
+	 * 
331
+	 * @return void
332
+	 */
333
+	public function clear()
334
+	{   
335
+		$this->cache = [];
336
+		$this->pivotAttributes = [];
337
+	}
338 338
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -66,7 +66,7 @@  discard block
 block discarded – undo
66 66
 
67 67
         $keyColumn = $this->entityMap->getKeyName();
68 68
 
69
-        foreach($results as $result) {
69
+        foreach ($results as $result) {
70 70
             $id = $result[$keyColumn];
71 71
 
72 72
             // Forget the ID field from the cache attributes
@@ -236,7 +236,7 @@  discard block
 block discarded – undo
236 236
 
237 237
         $keyName = $mapper->getEntityMap()->getKeyName();
238 238
 
239
-        return $class . '.' . $entity->getEntityAttribute($keyName);
239
+        return $class.'.'.$entity->getEntityAttribute($keyName);
240 240
     }
241 241
 
242 242
     /**
Please login to merge, or discard this patch.
src/System/ResultBuilder.php 3 patches
Doc Comments   -1 removed lines patch added patch discarded remove patch
@@ -37,7 +37,6 @@
 block discarded – undo
37 37
 
38 38
     /**
39 39
      * @param Mapper  $defaultMapper
40
-     * @param array   $eagerLoads
41 40
      */
42 41
     public function __construct(Mapper $defaultMapper)
43 42
     {
Please login to merge, or discard this patch.
Indentation   +316 added lines, -316 removed lines patch added patch discarded remove patch
@@ -7,320 +7,320 @@
 block discarded – undo
7 7
 
8 8
 class ResultBuilder
9 9
 {
10
-    /**
11
-     * The default mapper used to build entities with.
12
-     * @var \Analogue\ORM\System\Mapper
13
-     */
14
-    protected $defaultMapper;
15
-
16
-    /**
17
-     * Relations that will be eager loaded on this query
18
-     *
19
-     * @var array
20
-     */
21
-    protected $eagerLoads;
22
-
23
-    /**
24
-     * The Entity Map for the entity to build.
25
-     *
26
-     * @var \Analogue\ORM\EntityMap
27
-     */
28
-    protected $entityMap;
29
-
30
-    /**
31
-     * An array of builders used by this class to build necessary
32
-     * entities for each result type.
33
-     *
34
-     * @var array
35
-     */
36
-    protected $builders = [];
37
-
38
-    /**
39
-     * @param Mapper  $defaultMapper
40
-     * @param array   $eagerLoads
41
-     */
42
-    public function __construct(Mapper $defaultMapper)
43
-    {
44
-        $this->defaultMapper = $defaultMapper;
45
-        $this->entityMap = $defaultMapper->getEntityMap();
46
-    }
47
-
48
-    /**
49
-     * Convert a result set into an array of entities
50
-     *
51
-     * @param  array $results
52
-     * @param  array $eagerLoads  name of the relation to be eager loaded on the Entities
53
-     * @return \Illuminate\Support\Collection
54
-     */
55
-    public function build(array $results, array $eagerLoads)
56
-    {
57
-        // First, we'll cast every single result to array
58
-        $results = array_map(function($item) {
59
-            return (array) $item;
60
-        }, $results);     
61
-
62
-        // Then, we'll cache every single results as raw attributes, before 
63
-        // adding relationships, which will be cached when the relationship's
64
-        // query takes place.
65
-        $this->defaultMapper->getEntityCache()->add($results);
66
-
67
-        // Launch the queries related to eager loads, and match the 
68
-        // current result set to these loaded relationships.
69
-        $results = $this->queryEagerLoadedRelationships($results, $eagerLoads);
70
-
71
-        // Note : Maybe we could use a PolymorphicResultBuilder, which would
72
-        // be shared by both STI and polymorphic relations, as they share the 
73
-        // same process. 
74
-
75
-        switch ($this->entityMap->getInheritanceType()) {
76
-            case 'single_table':
77
-                return $this->buildUsingSingleTableInheritance($results);
78
-                break;
79
-
80
-            default:
81
-                return $this->buildWithDefaultMapper($results);
82
-                break;
83
-        }
84
-    }
85
-
86
-    /**  
87
-     * Launch queries on eager loaded relationships
88
-     * 
89
-     * @return array
90
-     */
91
-    protected function queryEagerLoadedRelationships(array $results, array $eagerLoads)
92
-    {
93
-        $this->eagerLoads = $this->parseRelations($eagerLoads);
94
-
95
-        return $this->eagerLoadRelations($results);
96
-    }
97
-
98
-    /**
99
-     * Parse a list of relations into individuals.
100
-     *
101
-     * @param  array $relations
102
-     * @return array
103
-     */
104
-    protected function parseRelations(array $relations)
105
-    {
106
-        $results = [];
107
-
108
-        foreach ($relations as $name => $constraints) {
109
-            // If the "relation" value is actually a numeric key, we can assume that no
110
-            // constraints have been specified for the eager load and we'll just put
111
-            // an empty Closure with the loader so that we can treat all the same.
112
-            if (is_numeric($name)) {
113
-                $f = function () {};
114
-
115
-                list($name, $constraints) = [$constraints, $f];
116
-            }
117
-
118
-            // We need to separate out any nested includes. Which allows the developers
119
-            // to load deep relationships using "dots" without stating each level of
120
-            // the relationship with its own key in the array of eager load names.
121
-            $results = $this->parseNested($name, $results);
122
-
123
-            $results[$name] = $constraints;
124
-        }
125
-
126
-        return $results;
127
-    }
128
-
129
-    /**
130
-     * Parse the nested relationships in a relation.
131
-     *
132
-     * @param  string $name
133
-     * @param  array  $results
134
-     * @return array
135
-     */
136
-    protected function parseNested($name, $results)
137
-    {
138
-        $progress = [];
139
-
140
-        // If the relation has already been set on the result array, we will not set it
141
-        // again, since that would override any constraints that were already placed
142
-        // on the relationships. We will only set the ones that are not specified.
143
-        foreach (explode('.', $name) as $segment) {
144
-            $progress[] = $segment;
145
-
146
-            if (!isset($results[$last = implode('.', $progress)])) {
147
-                $results[$last] = function () {};
148
-            }
149
-        }
150
-
151
-        return $results;
152
-    }
153
-
154
-    /**
155
-     * Eager load the relationships on a result set
156
-     *
157
-     * @param  array $results
158
-     * @return array
159
-     */
160
-    public function eagerLoadRelations(array $results)
161
-    {
162
-        foreach ($this->eagerLoads as $name => $constraints) {
163
-
164
-            // For nested eager loads we'll skip loading them here and they will be set as an
165
-            // eager load on the query to retrieve the relation so that they will be eager
166
-            // loaded on that query, because that is where they get hydrated as models.
167
-            if (strpos($name, '.') === false) {
168
-                $results = $this->loadRelation($results, $name, $constraints);
169
-            }
170
-        }
171
-
172
-        return $results;
173
-    }
174
-
175
-    /**
176
-     * Eagerly load the relationship on a set of entities.
177
-     *
178
-     * @param  array    $results
179
-     * @param  string   $name
180
-     * @param  \Closure $constraints
181
-     * @return array
182
-     */
183
-    protected function loadRelation(array $results, $name, Closure $constraints) : array
184
-    {
185
-        // First we will "back up" the existing where conditions on the query so we can
186
-        // add our eager constraints. Then we will merge the wheres that were on the
187
-        // query back to it in order that any where conditions might be specified.
188
-        $relation = $this->getRelation($name);
189
-
190
-        $relation->addEagerConstraints($results);
191
-
192
-        call_user_func($constraints, $relation);
193
-
194
-        // Once we have the results, we just match those back up to their parent models
195
-        // using the relationship instance. Then we just return the finished arrays
196
-        // of models which have been eagerly hydrated and are readied for return.
197
-
198
-        // Same, this step isn't necessary, as we take the inverse approach than Eloquent :
199
-        // filling the attributes before hydration, for more efficiency
200
-        //$relationshipResults = $relation->getEager();
201
-
202
-        return $relation->match($results, $name);
203
-    }
204
-
205
-    /**
206
-     * Get the relation instance for the given relation name.
207
-     *
208
-     * @param  string $relation
209
-     * @return \Analogue\ORM\Relationships\Relationship
210
-     */
211
-    public function getRelation($relation)
212
-    {
213
-        // We want to run a relationship query without any constrains so that we will
214
-        // not have to remove these where clauses manually which gets really hacky
215
-        // and is error prone while we remove the developer's own where clauses.
216
-        $query = Relationship::noConstraints(function () use ($relation) {
217
-            return $this->entityMap->$relation($this->defaultMapper->newInstance());
218
-        });
219
-
220
-        $nested = $this->nestedRelations($relation);
221
-
222
-        // If there are nested relationships set on the query, we will put those onto
223
-        // the query instances so that they can be handled after this relationship
224
-        // is loaded. In this way they will all trickle down as they are loaded.
225
-        if (count($nested) > 0) {
226
-            $query->getQuery()->with($nested);
227
-        }
228
-
229
-        return $query;
230
-    }
231
-
232
-    /**
233
-     * Get the deeply nested relations for a given top-level relation.
234
-     *
235
-     * @param  string $relation
236
-     * @return array
237
-     */
238
-    protected function nestedRelations($relation)
239
-    {
240
-        $nested = [];
241
-
242
-        // We are basically looking for any relationships that are nested deeper than
243
-        // the given top-level relationship. We will just check for any relations
244
-        // that start with the given top relations and adds them to our arrays.
245
-        foreach ($this->eagerLoads as $name => $constraints) {
246
-            if ($this->isNested($name, $relation)) {
247
-                $nested[substr($name, strlen($relation . '.'))] = $constraints;
248
-            }
249
-        }
250
-
251
-        return $nested;
252
-    }
253
-
254
-    /**
255
-     * Determine if the relationship is nested.
256
-     *
257
-     * @param  string $name
258
-     * @param  string $relation
259
-     * @return bool
260
-     */
261
-    protected function isNested($name, $relation)
262
-    {
263
-        $dots = str_contains($name, '.');
264
-
265
-        return $dots && starts_with($name, $relation . '.');
266
-    }
267
-
268
-    /**
269
-     * Build an entity from results, using the default mapper on this builder.
270
-     * This is the default build plan when no table inheritance is being used.
271
-     *
272
-     * @param  array $results
273
-     * @return Collection
274
-     */
275
-    protected function buildWithDefaultMapper(array $results)
276
-    {
277
-        $builder = new EntityBuilder($this->defaultMapper, array_keys($this->eagerLoads));
278
-
279
-        return collect($results)->map(function($item, $key) use ($builder) {
280
-
281
-            return $builder->build($item);
282
-        })->all();
283
-    }
284
-
285
-    /**
286
-     * Build an entity from results, using single table inheritance.
287
-     *
288
-     * @param  array $results
289
-     * @return Collection
290
-     */
291
-    protected function buildUsingSingleTableInheritance(array $results)
292
-    {
293
-        return collect($results)->map(function($item, $key) {
294
-            $builder = $this->builderForResult($item);
295
-            return $builder->build($item);
296
-        })->all();
297
-    }
298
-
299
-    /**
300
-     * Given a result array, return the entity builder needed to correctly
301
-     * build the result into an entity. If no getDiscriminatorColumnMap property
302
-     * has been defined on the EntityMap, we'll assume that the value stored in
303
-     * the $type column is the fully qualified class name of the entity and
304
-     * we'll use it instead.
305
-     *
306
-     * @param  array  $result
307
-     * @return EntityBuilder
308
-     */
309
-    protected function builderForResult(array $result)
310
-    {
311
-        $type = $result[$this->entityMap->getDiscriminatorColumn()];
312
-
313
-        $columnMap = $this->entityMap->getDiscriminatorColumnMap();
314
-
315
-        $class = isset($columnMap[$type]) ? $columnMap[$type]: $type;
316
-
317
-        if (!isset($this->builders[$type])) {
318
-            $this->builders[$type] = new EntityBuilder(
319
-                Manager::getInstance()->mapper($class), 
320
-                array_keys($this->eagerLoads)
321
-            );
322
-        }
323
-
324
-        return $this->builders[$type];
325
-    }
10
+	/**
11
+	 * The default mapper used to build entities with.
12
+	 * @var \Analogue\ORM\System\Mapper
13
+	 */
14
+	protected $defaultMapper;
15
+
16
+	/**
17
+	 * Relations that will be eager loaded on this query
18
+	 *
19
+	 * @var array
20
+	 */
21
+	protected $eagerLoads;
22
+
23
+	/**
24
+	 * The Entity Map for the entity to build.
25
+	 *
26
+	 * @var \Analogue\ORM\EntityMap
27
+	 */
28
+	protected $entityMap;
29
+
30
+	/**
31
+	 * An array of builders used by this class to build necessary
32
+	 * entities for each result type.
33
+	 *
34
+	 * @var array
35
+	 */
36
+	protected $builders = [];
37
+
38
+	/**
39
+	 * @param Mapper  $defaultMapper
40
+	 * @param array   $eagerLoads
41
+	 */
42
+	public function __construct(Mapper $defaultMapper)
43
+	{
44
+		$this->defaultMapper = $defaultMapper;
45
+		$this->entityMap = $defaultMapper->getEntityMap();
46
+	}
47
+
48
+	/**
49
+	 * Convert a result set into an array of entities
50
+	 *
51
+	 * @param  array $results
52
+	 * @param  array $eagerLoads  name of the relation to be eager loaded on the Entities
53
+	 * @return \Illuminate\Support\Collection
54
+	 */
55
+	public function build(array $results, array $eagerLoads)
56
+	{
57
+		// First, we'll cast every single result to array
58
+		$results = array_map(function($item) {
59
+			return (array) $item;
60
+		}, $results);     
61
+
62
+		// Then, we'll cache every single results as raw attributes, before 
63
+		// adding relationships, which will be cached when the relationship's
64
+		// query takes place.
65
+		$this->defaultMapper->getEntityCache()->add($results);
66
+
67
+		// Launch the queries related to eager loads, and match the 
68
+		// current result set to these loaded relationships.
69
+		$results = $this->queryEagerLoadedRelationships($results, $eagerLoads);
70
+
71
+		// Note : Maybe we could use a PolymorphicResultBuilder, which would
72
+		// be shared by both STI and polymorphic relations, as they share the 
73
+		// same process. 
74
+
75
+		switch ($this->entityMap->getInheritanceType()) {
76
+			case 'single_table':
77
+				return $this->buildUsingSingleTableInheritance($results);
78
+				break;
79
+
80
+			default:
81
+				return $this->buildWithDefaultMapper($results);
82
+				break;
83
+		}
84
+	}
85
+
86
+	/**  
87
+	 * Launch queries on eager loaded relationships
88
+	 * 
89
+	 * @return array
90
+	 */
91
+	protected function queryEagerLoadedRelationships(array $results, array $eagerLoads)
92
+	{
93
+		$this->eagerLoads = $this->parseRelations($eagerLoads);
94
+
95
+		return $this->eagerLoadRelations($results);
96
+	}
97
+
98
+	/**
99
+	 * Parse a list of relations into individuals.
100
+	 *
101
+	 * @param  array $relations
102
+	 * @return array
103
+	 */
104
+	protected function parseRelations(array $relations)
105
+	{
106
+		$results = [];
107
+
108
+		foreach ($relations as $name => $constraints) {
109
+			// If the "relation" value is actually a numeric key, we can assume that no
110
+			// constraints have been specified for the eager load and we'll just put
111
+			// an empty Closure with the loader so that we can treat all the same.
112
+			if (is_numeric($name)) {
113
+				$f = function () {};
114
+
115
+				list($name, $constraints) = [$constraints, $f];
116
+			}
117
+
118
+			// We need to separate out any nested includes. Which allows the developers
119
+			// to load deep relationships using "dots" without stating each level of
120
+			// the relationship with its own key in the array of eager load names.
121
+			$results = $this->parseNested($name, $results);
122
+
123
+			$results[$name] = $constraints;
124
+		}
125
+
126
+		return $results;
127
+	}
128
+
129
+	/**
130
+	 * Parse the nested relationships in a relation.
131
+	 *
132
+	 * @param  string $name
133
+	 * @param  array  $results
134
+	 * @return array
135
+	 */
136
+	protected function parseNested($name, $results)
137
+	{
138
+		$progress = [];
139
+
140
+		// If the relation has already been set on the result array, we will not set it
141
+		// again, since that would override any constraints that were already placed
142
+		// on the relationships. We will only set the ones that are not specified.
143
+		foreach (explode('.', $name) as $segment) {
144
+			$progress[] = $segment;
145
+
146
+			if (!isset($results[$last = implode('.', $progress)])) {
147
+				$results[$last] = function () {};
148
+			}
149
+		}
150
+
151
+		return $results;
152
+	}
153
+
154
+	/**
155
+	 * Eager load the relationships on a result set
156
+	 *
157
+	 * @param  array $results
158
+	 * @return array
159
+	 */
160
+	public function eagerLoadRelations(array $results)
161
+	{
162
+		foreach ($this->eagerLoads as $name => $constraints) {
163
+
164
+			// For nested eager loads we'll skip loading them here and they will be set as an
165
+			// eager load on the query to retrieve the relation so that they will be eager
166
+			// loaded on that query, because that is where they get hydrated as models.
167
+			if (strpos($name, '.') === false) {
168
+				$results = $this->loadRelation($results, $name, $constraints);
169
+			}
170
+		}
171
+
172
+		return $results;
173
+	}
174
+
175
+	/**
176
+	 * Eagerly load the relationship on a set of entities.
177
+	 *
178
+	 * @param  array    $results
179
+	 * @param  string   $name
180
+	 * @param  \Closure $constraints
181
+	 * @return array
182
+	 */
183
+	protected function loadRelation(array $results, $name, Closure $constraints) : array
184
+	{
185
+		// First we will "back up" the existing where conditions on the query so we can
186
+		// add our eager constraints. Then we will merge the wheres that were on the
187
+		// query back to it in order that any where conditions might be specified.
188
+		$relation = $this->getRelation($name);
189
+
190
+		$relation->addEagerConstraints($results);
191
+
192
+		call_user_func($constraints, $relation);
193
+
194
+		// Once we have the results, we just match those back up to their parent models
195
+		// using the relationship instance. Then we just return the finished arrays
196
+		// of models which have been eagerly hydrated and are readied for return.
197
+
198
+		// Same, this step isn't necessary, as we take the inverse approach than Eloquent :
199
+		// filling the attributes before hydration, for more efficiency
200
+		//$relationshipResults = $relation->getEager();
201
+
202
+		return $relation->match($results, $name);
203
+	}
204
+
205
+	/**
206
+	 * Get the relation instance for the given relation name.
207
+	 *
208
+	 * @param  string $relation
209
+	 * @return \Analogue\ORM\Relationships\Relationship
210
+	 */
211
+	public function getRelation($relation)
212
+	{
213
+		// We want to run a relationship query without any constrains so that we will
214
+		// not have to remove these where clauses manually which gets really hacky
215
+		// and is error prone while we remove the developer's own where clauses.
216
+		$query = Relationship::noConstraints(function () use ($relation) {
217
+			return $this->entityMap->$relation($this->defaultMapper->newInstance());
218
+		});
219
+
220
+		$nested = $this->nestedRelations($relation);
221
+
222
+		// If there are nested relationships set on the query, we will put those onto
223
+		// the query instances so that they can be handled after this relationship
224
+		// is loaded. In this way they will all trickle down as they are loaded.
225
+		if (count($nested) > 0) {
226
+			$query->getQuery()->with($nested);
227
+		}
228
+
229
+		return $query;
230
+	}
231
+
232
+	/**
233
+	 * Get the deeply nested relations for a given top-level relation.
234
+	 *
235
+	 * @param  string $relation
236
+	 * @return array
237
+	 */
238
+	protected function nestedRelations($relation)
239
+	{
240
+		$nested = [];
241
+
242
+		// We are basically looking for any relationships that are nested deeper than
243
+		// the given top-level relationship. We will just check for any relations
244
+		// that start with the given top relations and adds them to our arrays.
245
+		foreach ($this->eagerLoads as $name => $constraints) {
246
+			if ($this->isNested($name, $relation)) {
247
+				$nested[substr($name, strlen($relation . '.'))] = $constraints;
248
+			}
249
+		}
250
+
251
+		return $nested;
252
+	}
253
+
254
+	/**
255
+	 * Determine if the relationship is nested.
256
+	 *
257
+	 * @param  string $name
258
+	 * @param  string $relation
259
+	 * @return bool
260
+	 */
261
+	protected function isNested($name, $relation)
262
+	{
263
+		$dots = str_contains($name, '.');
264
+
265
+		return $dots && starts_with($name, $relation . '.');
266
+	}
267
+
268
+	/**
269
+	 * Build an entity from results, using the default mapper on this builder.
270
+	 * This is the default build plan when no table inheritance is being used.
271
+	 *
272
+	 * @param  array $results
273
+	 * @return Collection
274
+	 */
275
+	protected function buildWithDefaultMapper(array $results)
276
+	{
277
+		$builder = new EntityBuilder($this->defaultMapper, array_keys($this->eagerLoads));
278
+
279
+		return collect($results)->map(function($item, $key) use ($builder) {
280
+
281
+			return $builder->build($item);
282
+		})->all();
283
+	}
284
+
285
+	/**
286
+	 * Build an entity from results, using single table inheritance.
287
+	 *
288
+	 * @param  array $results
289
+	 * @return Collection
290
+	 */
291
+	protected function buildUsingSingleTableInheritance(array $results)
292
+	{
293
+		return collect($results)->map(function($item, $key) {
294
+			$builder = $this->builderForResult($item);
295
+			return $builder->build($item);
296
+		})->all();
297
+	}
298
+
299
+	/**
300
+	 * Given a result array, return the entity builder needed to correctly
301
+	 * build the result into an entity. If no getDiscriminatorColumnMap property
302
+	 * has been defined on the EntityMap, we'll assume that the value stored in
303
+	 * the $type column is the fully qualified class name of the entity and
304
+	 * we'll use it instead.
305
+	 *
306
+	 * @param  array  $result
307
+	 * @return EntityBuilder
308
+	 */
309
+	protected function builderForResult(array $result)
310
+	{
311
+		$type = $result[$this->entityMap->getDiscriminatorColumn()];
312
+
313
+		$columnMap = $this->entityMap->getDiscriminatorColumnMap();
314
+
315
+		$class = isset($columnMap[$type]) ? $columnMap[$type]: $type;
316
+
317
+		if (!isset($this->builders[$type])) {
318
+			$this->builders[$type] = new EntityBuilder(
319
+				Manager::getInstance()->mapper($class), 
320
+				array_keys($this->eagerLoads)
321
+			);
322
+		}
323
+
324
+		return $this->builders[$type];
325
+	}
326 326
 }
327 327
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -110,7 +110,7 @@  discard block
 block discarded – undo
110 110
             // constraints have been specified for the eager load and we'll just put
111 111
             // an empty Closure with the loader so that we can treat all the same.
112 112
             if (is_numeric($name)) {
113
-                $f = function () {};
113
+                $f = function() {};
114 114
 
115 115
                 list($name, $constraints) = [$constraints, $f];
116 116
             }
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
             $progress[] = $segment;
145 145
 
146 146
             if (!isset($results[$last = implode('.', $progress)])) {
147
-                $results[$last] = function () {};
147
+                $results[$last] = function() {};
148 148
             }
149 149
         }
150 150
 
@@ -213,7 +213,7 @@  discard block
 block discarded – undo
213 213
         // We want to run a relationship query without any constrains so that we will
214 214
         // not have to remove these where clauses manually which gets really hacky
215 215
         // and is error prone while we remove the developer's own where clauses.
216
-        $query = Relationship::noConstraints(function () use ($relation) {
216
+        $query = Relationship::noConstraints(function() use ($relation) {
217 217
             return $this->entityMap->$relation($this->defaultMapper->newInstance());
218 218
         });
219 219
 
@@ -244,7 +244,7 @@  discard block
 block discarded – undo
244 244
         // that start with the given top relations and adds them to our arrays.
245 245
         foreach ($this->eagerLoads as $name => $constraints) {
246 246
             if ($this->isNested($name, $relation)) {
247
-                $nested[substr($name, strlen($relation . '.'))] = $constraints;
247
+                $nested[substr($name, strlen($relation.'.'))] = $constraints;
248 248
             }
249 249
         }
250 250
 
@@ -262,7 +262,7 @@  discard block
 block discarded – undo
262 262
     {
263 263
         $dots = str_contains($name, '.');
264 264
 
265
-        return $dots && starts_with($name, $relation . '.');
265
+        return $dots && starts_with($name, $relation.'.');
266 266
     }
267 267
 
268 268
     /**
@@ -312,7 +312,7 @@  discard block
 block discarded – undo
312 312
 
313 313
         $columnMap = $this->entityMap->getDiscriminatorColumnMap();
314 314
 
315
-        $class = isset($columnMap[$type]) ? $columnMap[$type]: $type;
315
+        $class = isset($columnMap[$type]) ? $columnMap[$type] : $type;
316 316
 
317 317
         if (!isset($this->builders[$type])) {
318 318
             $this->builders[$type] = new EntityBuilder(
Please login to merge, or discard this patch.
src/System/Wrappers/Factory.php 2 patches
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -2,7 +2,6 @@
 block discarded – undo
2 2
 
3 3
 namespace Analogue\ORM\System\Wrappers;
4 4
 
5
-use Analogue\ORM\Mappable;
6 5
 use Analogue\ORM\System\Manager;
7 6
 use GeneratedHydrator\Configuration;
8 7
 
Please login to merge, or discard this patch.
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -8,31 +8,31 @@
 block discarded – undo
8 8
 
9 9
 class Factory
10 10
 {
11
-    /**
12
-     * Build the wrapper corresponding to the object's type
13
-     *
14
-     * @param  mixed $object
15
-     * @throws \Analogue\ORM\Exceptions\MappingException
16
-     * @return Wrapper
17
-     */
18
-    public function make($object)
19
-    {
20
-        $manager = Manager::getInstance();
11
+	/**
12
+	 * Build the wrapper corresponding to the object's type
13
+	 *
14
+	 * @param  mixed $object
15
+	 * @throws \Analogue\ORM\Exceptions\MappingException
16
+	 * @return Wrapper
17
+	 */
18
+	public function make($object)
19
+	{
20
+		$manager = Manager::getInstance();
21 21
 
22
-        // Instantiate hydrator. We'll need to optimize this and allow pre-generation
23
-        // of these hydrator, and get it, ideally, from the entityMap or the Mapper class,
24
-        // so it's only instantiated once
25
-        $config        = new Configuration(get_class($object));
26
-        $hydratorClass = $config->createFactory()->getHydratorClass();
27
-        $hydrator      = new $hydratorClass();
22
+		// Instantiate hydrator. We'll need to optimize this and allow pre-generation
23
+		// of these hydrator, and get it, ideally, from the entityMap or the Mapper class,
24
+		// so it's only instantiated once
25
+		$config        = new Configuration(get_class($object));
26
+		$hydratorClass = $config->createFactory()->getHydratorClass();
27
+		$hydrator      = new $hydratorClass();
28 28
         
29
-        if ($manager->isValueObject($object)) {
30
-            $entityMap = $manager->getValueMap($object);
31
-        } else {
32
-            $entityMap = $manager->mapper($object)->getEntityMap();
33
-        }
29
+		if ($manager->isValueObject($object)) {
30
+			$entityMap = $manager->getValueMap($object);
31
+		} else {
32
+			$entityMap = $manager->mapper($object)->getEntityMap();
33
+		}
34 34
 
35
-        // Build Wrapper
36
-        return new ObjectWrapper($object, $entityMap, $hydrator);
37
-    }
35
+		// Build Wrapper
36
+		return new ObjectWrapper($object, $entityMap, $hydrator);
37
+	}
38 38
 }
Please login to merge, or discard this patch.
src/System/Wrappers/ObjectWrapper.php 3 patches
Doc Comments   -1 removed lines patch added patch discarded remove patch
@@ -35,7 +35,6 @@
 block discarded – undo
35 35
     /**
36 36
      * Object Wrapper constructor
37 37
      * 
38
-     * @param mixed $object
39 38
      * @param Analogue\ORM\EntityMap $entityMap
40 39
      * 
41 40
      * @return  void
Please login to merge, or discard this patch.
Indentation   +202 added lines, -202 removed lines patch added patch discarded remove patch
@@ -10,219 +10,219 @@
 block discarded – undo
10 10
  */
11 11
 class ObjectWrapper extends Wrapper
12 12
 {
13
-    /** 
14
-     * Internal Representation of analogue's entity attributes
15
-     * 
16
-     * @var  array
17
-     */
18
-    protected $attributes = [];
19
-
20
-    /** 
21
-     * Object properties that are not a part of the entity attributes,
22
-     * but which are needed to correctly hydrate the Object
23
-     * 
24
-     * @var array
25
-     */
26
-    protected $unmanagedProperties = [];
27
-
28
-    /**
29
-     * The hydrator for the wrapped object
30
-     * 
31
-     * @var  HydratorInterface
32
-     */
33
-    protected $hydrator;
34
-
35
-    /**
36
-     * Object Wrapper constructor
37
-     * 
38
-     * @param mixed $object
39
-     * @param Analogue\ORM\EntityMap $entityMap
40
-     * 
41
-     * @return  void
42
-     */
43
-    public function __construct($entity, $entityMap, HydratorInterface $hydrator)
44
-    {
45
-        $this->hydrator = $hydrator;
46
-        parent::__construct($entity, $entityMap);
47
-        $this->attributes = $this->dehydrate($entity);
48
-    }
49
-
50
-    /**
51
-     * Returns the wrapped entity
52
-     *
53
-     * @return mixed
54
-     */
55
-    public function getObject()
56
-    {   
57
-        $this->hydrate();
58
-        return $this->entity;
59
-    }
60
-
61
-    /**  
62
-     * Extract entity attributes / properties to an array of attributes
63
-     * 
64
-     * @param  mixed $entity 
65
-     * @return array
66
-     */
67
-    protected function dehydrate($entity) : array
68
-    {
69
-        $properties = $this->hydrator->extract($entity);
70
-
71
-        $this->unmanagedProperties = array_except($properties, $this->getManagedProperties());
72
-
73
-        return $this->attributesFromProperties($properties);
74
-    }
75
-
76
-    /**  
77
-     * Hydrate object's properties/attribute from the internal array representation
78
-     * 
79
-     * @return mixed
80
-     */
81
-    public function hydrate()
82
-    {
83
-        $properties = $this->propertiesFromAttributes($this->attributes) + $this->unmanagedProperties;
84
-        $this->hydrator->hydrate($properties, $this->entity);
85
-    }
86
-
87
-    /**  
88
-     * Return properties that will be extracted from the entity
89
-     * 
90
-     * @return array
91
-     */
92
-    protected function getManagedProperties() : array
93
-    {
94
-        $properties = $this->entityMap->getProperties();
95
-
96
-        $attributesName = $this->entityMap->getAttributesArrayName();
13
+	/** 
14
+	 * Internal Representation of analogue's entity attributes
15
+	 * 
16
+	 * @var  array
17
+	 */
18
+	protected $attributes = [];
19
+
20
+	/** 
21
+	 * Object properties that are not a part of the entity attributes,
22
+	 * but which are needed to correctly hydrate the Object
23
+	 * 
24
+	 * @var array
25
+	 */
26
+	protected $unmanagedProperties = [];
27
+
28
+	/**
29
+	 * The hydrator for the wrapped object
30
+	 * 
31
+	 * @var  HydratorInterface
32
+	 */
33
+	protected $hydrator;
34
+
35
+	/**
36
+	 * Object Wrapper constructor
37
+	 * 
38
+	 * @param mixed $object
39
+	 * @param Analogue\ORM\EntityMap $entityMap
40
+	 * 
41
+	 * @return  void
42
+	 */
43
+	public function __construct($entity, $entityMap, HydratorInterface $hydrator)
44
+	{
45
+		$this->hydrator = $hydrator;
46
+		parent::__construct($entity, $entityMap);
47
+		$this->attributes = $this->dehydrate($entity);
48
+	}
49
+
50
+	/**
51
+	 * Returns the wrapped entity
52
+	 *
53
+	 * @return mixed
54
+	 */
55
+	public function getObject()
56
+	{   
57
+		$this->hydrate();
58
+		return $this->entity;
59
+	}
60
+
61
+	/**  
62
+	 * Extract entity attributes / properties to an array of attributes
63
+	 * 
64
+	 * @param  mixed $entity 
65
+	 * @return array
66
+	 */
67
+	protected function dehydrate($entity) : array
68
+	{
69
+		$properties = $this->hydrator->extract($entity);
70
+
71
+		$this->unmanagedProperties = array_except($properties, $this->getManagedProperties());
72
+
73
+		return $this->attributesFromProperties($properties);
74
+	}
75
+
76
+	/**  
77
+	 * Hydrate object's properties/attribute from the internal array representation
78
+	 * 
79
+	 * @return mixed
80
+	 */
81
+	public function hydrate()
82
+	{
83
+		$properties = $this->propertiesFromAttributes($this->attributes) + $this->unmanagedProperties;
84
+		$this->hydrator->hydrate($properties, $this->entity);
85
+	}
86
+
87
+	/**  
88
+	 * Return properties that will be extracted from the entity
89
+	 * 
90
+	 * @return array
91
+	 */
92
+	protected function getManagedProperties() : array
93
+	{
94
+		$properties = $this->entityMap->getProperties();
95
+
96
+		$attributesName = $this->entityMap->getAttributesArrayName();
97 97
         
98
-        return $attributesName == null ? $properties : array_merge($properties, [$attributesName]);
99
-    }
100
-
101
-    /** 
102
-     * Convert object's properties to analogue's internal attributes representation
103
-     * 
104
-     * @param  array  $properties 
105
-     * @return array
106
-     */
107
-    protected function attributesFromProperties(array $properties) : array
108
-    {
109
-        // First, we'll only keep the entities that are part of the Entity's
110
-        // attributes
111
-        $managedProperties = $this->getManagedProperties();
112
-
113
-        $properties = array_only($properties, $managedProperties);
114
-
115
-        // If the entity does not uses the attributes array to store
116
-        // part of its attributes, we'll directly return the properties
117
-        if(! $this->entityMap->usesAttributesArray()) {
118
-            return $properties;
119
-        }
120
-
121
-        $arrayName = $this->entityMap->getAttributesArrayName();
98
+		return $attributesName == null ? $properties : array_merge($properties, [$attributesName]);
99
+	}
100
+
101
+	/** 
102
+	 * Convert object's properties to analogue's internal attributes representation
103
+	 * 
104
+	 * @param  array  $properties 
105
+	 * @return array
106
+	 */
107
+	protected function attributesFromProperties(array $properties) : array
108
+	{
109
+		// First, we'll only keep the entities that are part of the Entity's
110
+		// attributes
111
+		$managedProperties = $this->getManagedProperties();
112
+
113
+		$properties = array_only($properties, $managedProperties);
114
+
115
+		// If the entity does not uses the attributes array to store
116
+		// part of its attributes, we'll directly return the properties
117
+		if(! $this->entityMap->usesAttributesArray()) {
118
+			return $properties;
119
+		}
120
+
121
+		$arrayName = $this->entityMap->getAttributesArrayName();
122 122
         
123
-        if(! array_key_exists($arrayName, $properties)) {
124
-            throw new MappingException("Property $arrayName not set on object of type ".$this->getEntityClass());
125
-        }
123
+		if(! array_key_exists($arrayName, $properties)) {
124
+			throw new MappingException("Property $arrayName not set on object of type ".$this->getEntityClass());
125
+		}
126 126
 
127
-        if(! is_array($properties[$arrayName])) {
128
-            throw new MappingException("Property $arrayName should be an array.");
129
-        }
127
+		if(! is_array($properties[$arrayName])) {
128
+			throw new MappingException("Property $arrayName should be an array.");
129
+		}
130 130
 
131
-        $attributes = $properties[$arrayName];
131
+		$attributes = $properties[$arrayName];
132 132
 
133
-        unset($properties[$arrayName]);
133
+		unset($properties[$arrayName]);
134 134
 
135
-        return $properties + $attributes;
136
-    }
135
+		return $properties + $attributes;
136
+	}
137 137
 
138
-    /**  
139
-     * Convert internal representation of attributes to an array of properties
140
-     * that can hydrate the actual object.
141
-     * 
142
-     * @param  array  $attributes 
143
-     * @return array
144
-     */
145
-    protected function propertiesFromAttributes(array $attributes) : array
146
-    {
147
-        $attributes = $this->attributes;
138
+	/**  
139
+	 * Convert internal representation of attributes to an array of properties
140
+	 * that can hydrate the actual object.
141
+	 * 
142
+	 * @param  array  $attributes 
143
+	 * @return array
144
+	 */
145
+	protected function propertiesFromAttributes(array $attributes) : array
146
+	{
147
+		$attributes = $this->attributes;
148 148
 
149
-        // Get all managed properties 
150
-        $propertyNames = $this->entityMap->getProperties();
149
+		// Get all managed properties 
150
+		$propertyNames = $this->entityMap->getProperties();
151 151
 
152
-        $propertyAttributes = array_only($attributes, $propertyNames);
153
-        $attributesArray = array_except($attributes, $propertyNames);
152
+		$propertyAttributes = array_only($attributes, $propertyNames);
153
+		$attributesArray = array_except($attributes, $propertyNames);
154 154
 
155
-        $attributesArrayName = $this->entityMap->getAttributesArrayName();
155
+		$attributesArrayName = $this->entityMap->getAttributesArrayName();
156 156
 
157
-        if($attributesArrayName) {
158
-            $propertyAttributes[$attributesArrayName] = $attributesArray;
159
-        }
157
+		if($attributesArrayName) {
158
+			$propertyAttributes[$attributesArrayName] = $attributesArray;
159
+		}
160 160
 
161
-        return $propertyAttributes;
162
-    }
161
+		return $propertyAttributes;
162
+	}
163 163
     
164
-    /**
165
-     * Method used by the mapper to set the object
166
-     * attribute raw values (hydration)
167
-     *
168
-     * @param array $attributes
169
-     *
170
-     * @return void
171
-     */
172
-    public function setEntityAttributes(array $attributes)
173
-    {
174
-        $this->attributes = $attributes;
175
-    }
176
-
177
-    /**
178
-     * Method used by the mapper to get the
179
-     * raw object's values.
180
-     *
181
-     * @return array
182
-     */
183
-    public function getEntityAttributes() : array
184
-    {
185
-        return $this->attributes;
186
-    }
187
-
188
-    /**
189
-     * Method used by the mapper to set raw
190
-     * key-value pair
191
-     *
192
-     * @param string $key
193
-     * @param string $value
194
-     *
195
-     * @return void
196
-     */
197
-    public function setEntityAttribute($key, $value)
198
-    {
199
-        $this->attributes[$key] = $value;
200
-    }
201
-
202
-    /**
203
-     * Method used by the mapper to get single
204
-     * key-value pair
205
-     *
206
-     * @param  string $key
207
-     * @return mixed|null
208
-     */
209
-    public function getEntityAttribute($key)
210
-    {
211
-        if ($this->hasAttribute($key)) {
212
-            return $this->attributes[$key];
213
-        } else {
214
-            return null;
215
-        }
216
-    }
217
-
218
-    /**
219
-     * Test if a given attribute exists
220
-     *
221
-     * @param  string $key
222
-     * @return boolean
223
-     */
224
-    public function hasAttribute($key) : bool
225
-    {
226
-        return array_key_exists($key, $this->attributes) ? true : false;
227
-    }
164
+	/**
165
+	 * Method used by the mapper to set the object
166
+	 * attribute raw values (hydration)
167
+	 *
168
+	 * @param array $attributes
169
+	 *
170
+	 * @return void
171
+	 */
172
+	public function setEntityAttributes(array $attributes)
173
+	{
174
+		$this->attributes = $attributes;
175
+	}
176
+
177
+	/**
178
+	 * Method used by the mapper to get the
179
+	 * raw object's values.
180
+	 *
181
+	 * @return array
182
+	 */
183
+	public function getEntityAttributes() : array
184
+	{
185
+		return $this->attributes;
186
+	}
187
+
188
+	/**
189
+	 * Method used by the mapper to set raw
190
+	 * key-value pair
191
+	 *
192
+	 * @param string $key
193
+	 * @param string $value
194
+	 *
195
+	 * @return void
196
+	 */
197
+	public function setEntityAttribute($key, $value)
198
+	{
199
+		$this->attributes[$key] = $value;
200
+	}
201
+
202
+	/**
203
+	 * Method used by the mapper to get single
204
+	 * key-value pair
205
+	 *
206
+	 * @param  string $key
207
+	 * @return mixed|null
208
+	 */
209
+	public function getEntityAttribute($key)
210
+	{
211
+		if ($this->hasAttribute($key)) {
212
+			return $this->attributes[$key];
213
+		} else {
214
+			return null;
215
+		}
216
+	}
217
+
218
+	/**
219
+	 * Test if a given attribute exists
220
+	 *
221
+	 * @param  string $key
222
+	 * @return boolean
223
+	 */
224
+	public function hasAttribute($key) : bool
225
+	{
226
+		return array_key_exists($key, $this->attributes) ? true : false;
227
+	}
228 228
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -114,17 +114,17 @@  discard block
 block discarded – undo
114 114
 
115 115
         // If the entity does not uses the attributes array to store
116 116
         // part of its attributes, we'll directly return the properties
117
-        if(! $this->entityMap->usesAttributesArray()) {
117
+        if (!$this->entityMap->usesAttributesArray()) {
118 118
             return $properties;
119 119
         }
120 120
 
121 121
         $arrayName = $this->entityMap->getAttributesArrayName();
122 122
         
123
-        if(! array_key_exists($arrayName, $properties)) {
123
+        if (!array_key_exists($arrayName, $properties)) {
124 124
             throw new MappingException("Property $arrayName not set on object of type ".$this->getEntityClass());
125 125
         }
126 126
 
127
-        if(! is_array($properties[$arrayName])) {
127
+        if (!is_array($properties[$arrayName])) {
128 128
             throw new MappingException("Property $arrayName should be an array.");
129 129
         }
130 130
 
@@ -154,7 +154,7 @@  discard block
 block discarded – undo
154 154
 
155 155
         $attributesArrayName = $this->entityMap->getAttributesArrayName();
156 156
 
157
-        if($attributesArrayName) {
157
+        if ($attributesArrayName) {
158 158
             $propertyAttributes[$attributesArrayName] = $attributesArray;
159 159
         }
160 160
 
Please login to merge, or discard this patch.
src/ValueMap.php 2 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -71,7 +71,7 @@  discard block
 block discarded – undo
71 71
     }
72 72
 
73 73
     /**
74
-     * @param $class
74
+     * @param string $class
75 75
      */
76 76
     public function setClass($class)
77 77
     {
@@ -79,7 +79,7 @@  discard block
 block discarded – undo
79 79
     }
80 80
 
81 81
     /**
82
-     * @return mixed
82
+     * @return string
83 83
      */
84 84
     public function getClass()
85 85
     {
Please login to merge, or discard this patch.
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -4,97 +4,97 @@
 block discarded – undo
4 4
 
5 5
 class ValueMap
6 6
 {
7
-    /**
8
-     * @var string
9
-     */
10
-    protected $name;
7
+	/**
8
+	 * @var string
9
+	 */
10
+	protected $name;
11 11
 
12
-    /**
13
-     * @var string
14
-     */
15
-    protected $class;
12
+	/**
13
+	 * @var string
14
+	 */
15
+	protected $class;
16 16
 
17
-    /**
18
-     * @var array
19
-     */
20
-    protected $embeddables = [];
17
+	/**
18
+	 * @var array
19
+	 */
20
+	protected $embeddables = [];
21 21
 
22
-    /**
23
-     * @var array
24
-     */
25
-    protected $attributes = [];
22
+	/**
23
+	 * @var array
24
+	 */
25
+	protected $attributes = [];
26 26
 
27
-    /**
28
-     * @var  array
29
-     */
30
-    protected $properties = [];
27
+	/**
28
+	 * @var  array
29
+	 */
30
+	protected $properties = [];
31 31
 
32
-    protected $arrayName = null;
32
+	protected $arrayName = null;
33 33
 
34
-    /**
35
-     * @return array
36
-     */
37
-    public function getAttributes()
38
-    {
39
-        return $this->attributes;
40
-    }
34
+	/**
35
+	 * @return array
36
+	 */
37
+	public function getAttributes()
38
+	{
39
+		return $this->attributes;
40
+	}
41 41
 
42
-    /**  
43
-     * [getAttributesArrayName description]
44
-     * @return [type] [description]
45
-     */
46
-    public function getAttributesArrayName()
47
-    {
48
-        return $this->arrayName;
49
-    }
42
+	/**  
43
+	 * [getAttributesArrayName description]
44
+	 * @return [type] [description]
45
+	 */
46
+	public function getAttributesArrayName()
47
+	{
48
+		return $this->arrayName;
49
+	}
50 50
 
51
-    public function usesAttributesArray()
52
-    {
53
-        return $this->arrayName != null;
54
-    }
51
+	public function usesAttributesArray()
52
+	{
53
+		return $this->arrayName != null;
54
+	}
55 55
 
56
-    /**  
57
-     * 
58
-     * @return array
59
-     */
60
-    public function getProperties()
61
-    {
62
-        return $this->properties;
63
-    }
56
+	/**  
57
+	 * 
58
+	 * @return array
59
+	 */
60
+	public function getProperties()
61
+	{
62
+		return $this->properties;
63
+	}
64 64
 
65
-    /**
66
-     * @return array
67
-     */
68
-    public function getEmbeddables()
69
-    {
70
-        return $this->embeddables;
71
-    }
65
+	/**
66
+	 * @return array
67
+	 */
68
+	public function getEmbeddables()
69
+	{
70
+		return $this->embeddables;
71
+	}
72 72
 
73
-    /**
74
-     * @param $class
75
-     */
76
-    public function setClass($class)
77
-    {
78
-        $this->class = $class;
79
-    }
73
+	/**
74
+	 * @param $class
75
+	 */
76
+	public function setClass($class)
77
+	{
78
+		$this->class = $class;
79
+	}
80 80
 
81
-    /**
82
-     * @return mixed
83
-     */
84
-    public function getClass()
85
-    {
86
-        return $this->class;
87
-    }
81
+	/**
82
+	 * @return mixed
83
+	 */
84
+	public function getClass()
85
+	{
86
+		return $this->class;
87
+	}
88 88
 
89
-    /**
90
-     * @return string
91
-     */
92
-    public function getName()
93
-    {
94
-        if (isset($this->name)) {
95
-            return $this->name;
96
-        } else {
97
-            return class_basename($this);
98
-        }
99
-    }
89
+	/**
90
+	 * @return string
91
+	 */
92
+	public function getName()
93
+	{
94
+		if (isset($this->name)) {
95
+			return $this->name;
96
+		} else {
97
+			return class_basename($this);
98
+		}
99
+	}
100 100
 }
Please login to merge, or discard this patch.
src/Commands/Store.php 1 patch
Indentation   +227 added lines, -227 removed lines patch added patch discarded remove patch
@@ -14,244 +14,244 @@
 block discarded – undo
14 14
  */
15 15
 class Store extends Command
16 16
 {
17
-    /**
18
-     * Persist the entity in the database
19
-     *
20
-     * @throws \InvalidArgumentException
21
-     * @return false|mixed
22
-     */
23
-    public function execute()
24
-    {
25
-        $entity = $this->aggregate->getEntityObject();
26
-
27
-        $mapper = $this->aggregate->getMapper();
28
-
29
-        if ($mapper->fireEvent('storing', $entity) === false) {
30
-            return false;
31
-        }
32
-
33
-        $this->preStoreProcess();
34
-
35
-        /**
36
-         * We will test the entity for existence
37
-         * and run a creation if it doesn't exists
38
-         */
39
-        if (!$this->aggregate->exists()) {
40
-            if ($mapper->fireEvent('creating', $entity) === false) {
41
-                return false;
42
-            }
43
-
44
-            $this->insert();
45
-
46
-            $mapper->fireEvent('created', $entity, false);
47
-        }
48
-        else if ($this->aggregate->isDirty()) {
49
-            if ($mapper->fireEvent('updating', $entity) === false) {
50
-                return false;
51
-            }
52
-            $this->update();
53
-
54
-            $mapper->fireEvent('updated', $entity, false);
55
-        }
56
-
57
-        $this->postStoreProcess();
58
-
59
-        $mapper->fireEvent('stored', $entity, false);
60
-
61
-        // Then we need to hydrate the actual entity
62
-        $this->aggregate->hydrate();
63
-
64
-        return $entity;
65
-    }
66
-
67
-    /**
68
-     * Run all operations that have to occur before actually
69
-     * storing the entity
70
-     *
71
-     * @throws \InvalidArgumentException
72
-     * @return void
73
-     */
74
-    protected function preStoreProcess()
75
-    {
76
-        // Create any related object that doesn't exist in the database.
77
-        $localRelationships = $this->aggregate->getEntityMap()->getLocalRelationships();
78
-
79
-        $this->createRelatedEntities($localRelationships);
80
-
81
-        // Now we can sync the related collections
82
-        $this->aggregate->syncRelationships($localRelationships);
83
-    }
84
-
85
-    /**
86
-     * Check for existence and create non-existing related entities
87
-     *
88
-     * @param  array
89
-     * @throws \InvalidArgumentException
90
-     * @return void
91
-     */
92
-    protected function createRelatedEntities($relations)
93
-    {
94
-        $entitiesToCreate = $this->aggregate->getNonExistingRelated($relations);
95
-
96
-        foreach ($entitiesToCreate as $aggregate) {
97
-            $this->createStoreCommand($aggregate)->execute();
98
-        }
17
+	/**
18
+	 * Persist the entity in the database
19
+	 *
20
+	 * @throws \InvalidArgumentException
21
+	 * @return false|mixed
22
+	 */
23
+	public function execute()
24
+	{
25
+		$entity = $this->aggregate->getEntityObject();
26
+
27
+		$mapper = $this->aggregate->getMapper();
28
+
29
+		if ($mapper->fireEvent('storing', $entity) === false) {
30
+			return false;
31
+		}
32
+
33
+		$this->preStoreProcess();
34
+
35
+		/**
36
+		 * We will test the entity for existence
37
+		 * and run a creation if it doesn't exists
38
+		 */
39
+		if (!$this->aggregate->exists()) {
40
+			if ($mapper->fireEvent('creating', $entity) === false) {
41
+				return false;
42
+			}
43
+
44
+			$this->insert();
45
+
46
+			$mapper->fireEvent('created', $entity, false);
47
+		}
48
+		else if ($this->aggregate->isDirty()) {
49
+			if ($mapper->fireEvent('updating', $entity) === false) {
50
+				return false;
51
+			}
52
+			$this->update();
53
+
54
+			$mapper->fireEvent('updated', $entity, false);
55
+		}
56
+
57
+		$this->postStoreProcess();
58
+
59
+		$mapper->fireEvent('stored', $entity, false);
60
+
61
+		// Then we need to hydrate the actual entity
62
+		$this->aggregate->hydrate();
63
+
64
+		return $entity;
65
+	}
66
+
67
+	/**
68
+	 * Run all operations that have to occur before actually
69
+	 * storing the entity
70
+	 *
71
+	 * @throws \InvalidArgumentException
72
+	 * @return void
73
+	 */
74
+	protected function preStoreProcess()
75
+	{
76
+		// Create any related object that doesn't exist in the database.
77
+		$localRelationships = $this->aggregate->getEntityMap()->getLocalRelationships();
78
+
79
+		$this->createRelatedEntities($localRelationships);
80
+
81
+		// Now we can sync the related collections
82
+		$this->aggregate->syncRelationships($localRelationships);
83
+	}
84
+
85
+	/**
86
+	 * Check for existence and create non-existing related entities
87
+	 *
88
+	 * @param  array
89
+	 * @throws \InvalidArgumentException
90
+	 * @return void
91
+	 */
92
+	protected function createRelatedEntities($relations)
93
+	{
94
+		$entitiesToCreate = $this->aggregate->getNonExistingRelated($relations);
95
+
96
+		foreach ($entitiesToCreate as $aggregate) {
97
+			$this->createStoreCommand($aggregate)->execute();
98
+		}
99 99
         
100
-    }
101
-
102
-    /**
103
-     * Create a new store command
104
-     *
105
-     * @param  Aggregate $aggregate
106
-     * @return Store
107
-     */
108
-    protected function createStoreCommand(Aggregate $aggregate)
109
-    {
110
-        // We gotta retrieve the corresponding query adapter to use.
111
-        $mapper = $aggregate->getMapper();
112
-
113
-        return new Store($aggregate, $mapper->newQueryBuilder());
114
-    }
115
-
116
-    /**
117
-     * Run all operations that have to occur after the entity
118
-     * is stored.
119
-     *
120
-     * @throws \InvalidArgumentException
121
-     * @return void
122
-     */
123
-    protected function postStoreProcess()
124
-    {
125
-        $aggregate = $this->aggregate;
126
-
127
-        // Create any related object that doesn't exist in the database.
128
-        $foreignRelationships = $aggregate->getEntityMap()->getForeignRelationships();
129
-
130
-        $this->createRelatedEntities($foreignRelationships);
131
-
132
-        // Update any pivot tables that has been modified.
133
-        $aggregate->updatePivotRecords();
134
-
135
-        // Update any dirty relationship. This include relationships that already exists, have
136
-        // dirty attributes / newly created related entities / dirty related entities.
137
-        $dirtyRelatedAggregates = $aggregate->getDirtyRelationships();
100
+	}
101
+
102
+	/**
103
+	 * Create a new store command
104
+	 *
105
+	 * @param  Aggregate $aggregate
106
+	 * @return Store
107
+	 */
108
+	protected function createStoreCommand(Aggregate $aggregate)
109
+	{
110
+		// We gotta retrieve the corresponding query adapter to use.
111
+		$mapper = $aggregate->getMapper();
112
+
113
+		return new Store($aggregate, $mapper->newQueryBuilder());
114
+	}
115
+
116
+	/**
117
+	 * Run all operations that have to occur after the entity
118
+	 * is stored.
119
+	 *
120
+	 * @throws \InvalidArgumentException
121
+	 * @return void
122
+	 */
123
+	protected function postStoreProcess()
124
+	{
125
+		$aggregate = $this->aggregate;
126
+
127
+		// Create any related object that doesn't exist in the database.
128
+		$foreignRelationships = $aggregate->getEntityMap()->getForeignRelationships();
129
+
130
+		$this->createRelatedEntities($foreignRelationships);
131
+
132
+		// Update any pivot tables that has been modified.
133
+		$aggregate->updatePivotRecords();
134
+
135
+		// Update any dirty relationship. This include relationships that already exists, have
136
+		// dirty attributes / newly created related entities / dirty related entities.
137
+		$dirtyRelatedAggregates = $aggregate->getDirtyRelationships();
138 138
         
139
-        foreach ($dirtyRelatedAggregates as $related) {
140
-            $this->createStoreCommand($related)->execute();
141
-        }
142
-
143
-        // Now we can sync the related collections
144
-        // 
145
-        // TODO (note) : not sute this check is needed, as we can assume
146
-        // the aggregate exists in the Post Store Process
147
-        if ($this->aggregate->exists()) {
148
-            $this->aggregate->syncRelationships($foreignRelationships);
149
-        }
139
+		foreach ($dirtyRelatedAggregates as $related) {
140
+			$this->createStoreCommand($related)->execute();
141
+		}
142
+
143
+		// Now we can sync the related collections
144
+		// 
145
+		// TODO (note) : not sute this check is needed, as we can assume
146
+		// the aggregate exists in the Post Store Process
147
+		if ($this->aggregate->exists()) {
148
+			$this->aggregate->syncRelationships($foreignRelationships);
149
+		}
150 150
         
151
-        // TODO be move it to the wrapper class
152
-        // so it's the same code for the entity builder
153
-        $aggregate->setProxies();
154
-
155
-        // Update Entity Cache
156
-        $aggregate->getMapper()->getEntityCache()->refresh($aggregate);
157
-    }
158
-
159
-    /**
160
-     * Update Related Entities which attributes have
161
-     * been modified.
162
-     *
163
-     * @return void
164
-     */
165
-    protected function updateDirtyRelated()
166
-    {
167
-        $relations = $this->entityMap->getRelationships();
168
-        $attributes = $this->getAttributes();
169
-
170
-        foreach ($relations as $relation) {
171
-            if (!array_key_exists($relation, $attributes)) {
172
-                continue;
173
-            }
174
-
175
-            $value = $attributes[$relation];
176
-
177
-            if ($value == null) {
178
-                continue;
179
-            }
180
-
181
-            if ($value instanceof EntityProxy) {
182
-                continue;
183
-            }
184
-
185
-            if ($value instanceof CollectionProxy && $value->isLoaded()) {
186
-                $value = $value->getUnderlyingCollection();
187
-            }
188
-            if ($value instanceof CollectionProxy && !$value->isLoaded()) {
189
-                foreach ($value->getAddedItems() as $entity) {
190
-                    $this->updateEntityIfDirty($entity);
191
-                }
192
-                continue;
193
-            }
194
-
195
-            if ($value instanceof EntityCollection) {
196
-                foreach ($value as $entity) {
197
-                    if (!$this->createEntityIfNotExists($entity)) {
198
-                        $this->updateEntityIfDirty($entity);
199
-                    }
200
-                }
201
-                continue;
202
-            }
203
-            if ($value instanceof Mappable) {
204
-                $this->updateEntityIfDirty($value);
205
-                continue;
206
-            }
207
-        }
208
-    }
209
-
210
-    /**
211
-     * Execute an insert statement on the database
212
-     *
213
-     * @return void
214
-     */
215
-    protected function insert()
216
-    {
217
-        $aggregate = $this->aggregate;
218
-
219
-        $attributes = $aggregate->getRawAttributes();
151
+		// TODO be move it to the wrapper class
152
+		// so it's the same code for the entity builder
153
+		$aggregate->setProxies();
154
+
155
+		// Update Entity Cache
156
+		$aggregate->getMapper()->getEntityCache()->refresh($aggregate);
157
+	}
158
+
159
+	/**
160
+	 * Update Related Entities which attributes have
161
+	 * been modified.
162
+	 *
163
+	 * @return void
164
+	 */
165
+	protected function updateDirtyRelated()
166
+	{
167
+		$relations = $this->entityMap->getRelationships();
168
+		$attributes = $this->getAttributes();
169
+
170
+		foreach ($relations as $relation) {
171
+			if (!array_key_exists($relation, $attributes)) {
172
+				continue;
173
+			}
174
+
175
+			$value = $attributes[$relation];
176
+
177
+			if ($value == null) {
178
+				continue;
179
+			}
180
+
181
+			if ($value instanceof EntityProxy) {
182
+				continue;
183
+			}
184
+
185
+			if ($value instanceof CollectionProxy && $value->isLoaded()) {
186
+				$value = $value->getUnderlyingCollection();
187
+			}
188
+			if ($value instanceof CollectionProxy && !$value->isLoaded()) {
189
+				foreach ($value->getAddedItems() as $entity) {
190
+					$this->updateEntityIfDirty($entity);
191
+				}
192
+				continue;
193
+			}
194
+
195
+			if ($value instanceof EntityCollection) {
196
+				foreach ($value as $entity) {
197
+					if (!$this->createEntityIfNotExists($entity)) {
198
+						$this->updateEntityIfDirty($entity);
199
+					}
200
+				}
201
+				continue;
202
+			}
203
+			if ($value instanceof Mappable) {
204
+				$this->updateEntityIfDirty($value);
205
+				continue;
206
+			}
207
+		}
208
+	}
209
+
210
+	/**
211
+	 * Execute an insert statement on the database
212
+	 *
213
+	 * @return void
214
+	 */
215
+	protected function insert()
216
+	{
217
+		$aggregate = $this->aggregate;
218
+
219
+		$attributes = $aggregate->getRawAttributes();
220 220
         
221
-        $keyName = $aggregate->getEntityMap()->getKeyName();
221
+		$keyName = $aggregate->getEntityMap()->getKeyName();
222 222
 
223
-        // Check if the primary key is defined in the attributes
224
-        if (array_key_exists($keyName, $attributes) && $attributes[$keyName] != null) {
225
-            $this->query->insert($attributes);
226
-        } else {
227
-            $sequence = $aggregate->getEntityMap()->getSequence();
223
+		// Check if the primary key is defined in the attributes
224
+		if (array_key_exists($keyName, $attributes) && $attributes[$keyName] != null) {
225
+			$this->query->insert($attributes);
226
+		} else {
227
+			$sequence = $aggregate->getEntityMap()->getSequence();
228 228
 
229
-            $id = $this->query->insertGetId($attributes, $sequence);
229
+			$id = $this->query->insertGetId($attributes, $sequence);
230 230
 
231
-            $aggregate->setEntityAttribute($keyName, $id);
232
-        }
231
+			$aggregate->setEntityAttribute($keyName, $id);
232
+		}
233 233
 
234
-    }
234
+	}
235 235
 
236
-    /**
237
-     * Run an update statement on the entity
238
-     *
239
-     * @throws \InvalidArgumentException
240
-     *
241
-     * @return void
242
-     */
243
-    protected function update()
244
-    {
245
-        $query = $this->query;
236
+	/**
237
+	 * Run an update statement on the entity
238
+	 *
239
+	 * @throws \InvalidArgumentException
240
+	 *
241
+	 * @return void
242
+	 */
243
+	protected function update()
244
+	{
245
+		$query = $this->query;
246 246
 
247
-        $keyName = $this->aggregate->getEntityKey();
247
+		$keyName = $this->aggregate->getEntityKey();
248 248
 
249
-        $query = $query->where($keyName, '=', $this->aggregate->getEntityId());
249
+		$query = $query->where($keyName, '=', $this->aggregate->getEntityId());
250 250
 
251
-        $dirtyAttributes = $this->aggregate->getDirtyRawAttributes();
251
+		$dirtyAttributes = $this->aggregate->getDirtyRawAttributes();
252 252
 
253
-        if (count($dirtyAttributes) > 0) {
254
-            $query->update($dirtyAttributes);
255
-        }
256
-    }
253
+		if (count($dirtyAttributes) > 0) {
254
+			$query->update($dirtyAttributes);
255
+		}
256
+	}
257 257
 }
Please login to merge, or discard this patch.
src/EntityMap.php 2 patches
Indentation   +1388 added lines, -1388 removed lines patch added patch discarded remove patch
@@ -23,1409 +23,1409 @@
 block discarded – undo
23 23
  */
24 24
 class EntityMap
25 25
 {
26
-    /**
27
-     * The mapping driver to use with this entity
28
-     *
29
-     * @var  string
30
-     */
31
-    protected $driver = 'illuminate';
32
-
33
-    /**
34
-     * The Database Connection name for the model.
35
-     *
36
-     * @var string
37
-     */
38
-    protected $connection;
39
-
40
-    /**
41
-     * The table associated with the entity.
42
-     *
43
-     * @var string|null
44
-     */
45
-    protected $table = null;
46
-
47
-    /**
48
-     * The primary key for the model.
49
-     *
50
-     * @var string
51
-     */
52
-    protected $primaryKey = 'id';
53
-
54
-    /**
55
-     * Name of the entity's array property that should
56
-     * contain the attributes. 
57
-     * If set to null, analogue will only hydrate object's properties
58
-     * 
59
-     * @var string|null
60
-     */
61
-    protected $arrayName = 'attributes';
62
-
63
-    /**
64
-     * Array containing the list of database columns to be mapped
65
-     * in the attributes array of the entity. 
66
-     *
67
-     * @var array
68
-     */
69
-    protected $attributes = [];
70
-
71
-    /**
72
-     * Array containing the list of database columns to be mapped
73
-     * to the entity's class properties. 
74
-     *
75
-     * @var array
76
-     */
77
-    protected $properties = [];
78
-
79
-    /**
80
-     * The Custom Domain Class to use with this mapping
81
-     *
82
-     * @var string|null
83
-     */
84
-    protected $class = null;
85
-
86
-    /**
87
-     * Embedded Value Objects
88
-     * 
89
-     * @var array
90
-     */
91
-    protected $embeddables = [];
92
-
93
-    /**
94
-     * Determine the relationships method used on the entity.
95
-     * If not set, mapper will autodetect them
96
-     *
97
-     * @var array
98
-     */
99
-    private $relationships = [];
100
-
101
-    /**
102
-     * Relationships that should be treated as collection.
103
-     *
104
-     * @var array
105
-     */
106
-    private $manyRelations = [];
107
-
108
-    /**
109
-     * Relationships that should be treated as single entity.
110
-     *
111
-     * @var array
112
-     */
113
-    private $singleRelations = [];
114
-
115
-    /**
116
-     * Relationships for which the key is stored in the Entity itself
117
-     *
118
-     * @var array
119
-     */
120
-    private $localRelations = [];
121
-
122
-    /** 
123
-     * List of local keys associated to local relation methods
124
-     * 
125
-     * @var array
126
-     */
127
-    private $localForeignKeys = [];
128
-
129
-    /**
130
-     * Relationships for which the key is stored in the Related Entity
131
-     *
132
-     * @var array
133
-     */
134
-    private $foreignRelations = [];
135
-
136
-    /**
137
-     * Relationships which use a pivot record.
138
-     *
139
-     * @var array
140
-     */
141
-    private $pivotRelations = [];
142
-
143
-    /**
144
-     * Dynamic relationships
145
-     *
146
-     * @var array
147
-     */
148
-    private $dynamicRelationships = [];
149
-
150
-    /**
151
-     * Targetted class for the relationship method. value is set to `null` for
152
-     * polymorphic relations. 
153
-     * 
154
-     * @var array
155
-     */
156
-    private $relatedClasses = [];
157
-
158
-    /** 
159
-     * Some relation methods like embedded objects, or HasOne and MorphOne,
160
-     * will never have a proxy loaded on them. 
161
-     * 
162
-     * @var  array
163
-     */
164
-    private $nonProxyRelationships = [];
165
-
166
-    /**
167
-     * The number of models to return for pagination.
168
-     *
169
-     * @var int
170
-     */
171
-    protected $perPage = 15;
172
-
173
-    /**
174
-     * The relations to eager load on every query.
175
-     *
176
-     * @var array
177
-     */
178
-    protected $with = [];
179
-
180
-    /**
181
-     * The class name to be used in polymorphic relations.
182
-     *
183
-     * @var string
184
-     */
185
-    protected $morphClass;
186
-
187
-    /**
188
-     * Sequence name, to be used with postgreSql
189
-     * defaults to %table_name%_id_seq
190
-     *
191
-     * @var string|null
192
-     */
193
-    protected $sequence = null;
194
-
195
-    /**
196
-     * Indicates if the entity should be timestamped.
197
-     *
198
-     * @var bool
199
-     */
200
-    public $timestamps = false;
201
-
202
-    /**
203
-     * The name of the "created at" column.
204
-     *
205
-     * @var string
206
-     */
207
-    protected $createdAtColumn = 'created_at';
208
-
209
-    /**
210
-     * The name of the "updated at" column.
211
-     *
212
-     * @var string
213
-     */
214
-    protected $updatedAtColumn = 'updated_at';
215
-
216
-    /**
217
-     * Indicates if the entity uses softdeletes
218
-     *
219
-     * @var boolean
220
-     */
221
-    public $softDeletes = false;
222
-
223
-    /**
224
-     * The name of the "deleted at" column.
225
-     *
226
-     * @var string
227
-     */
228
-    protected $deletedAtColumn = 'deleted_at';
229
-
230
-    /**
231
-     * The date format to use with the current database connection
232
-     *
233
-     * @var string
234
-     */
235
-    protected $dateFormat;
236
-
237
-    /**
238
-     * Set this property to true if the entity should be instantiated
239
-     * using the IoC Container
240
-     * 
241
-     * @var boolean
242
-     */
243
-    protected $dependencyInjection = false;
244
-
245
-    /**
246
-     * Set the usage of inheritance, possible values are :
247
-     * "single_table"
248
-     * null
249
-     * 
250
-     * @var string | null
251
-     */
252
-    protected $inheritanceType = null;
253
-
254
-    /**
255
-     * Discriminator column name
256
-     * 
257
-     * @var string
258
-     */
259
-    protected $discriminatorColumn = "type";
260
-
261
-    /**
262
-     * Allow using a string to define which entity type should be instantiated.
263
-     * If not set, analogue will uses entity's FQDN
264
-     * 
265
-     * @var array
266
-     */
267
-    protected $discriminatorColumnMap = [];
268
-
269
-    /**
270
-     * Return Domain class attributes, useful when mapping to a Plain PHP Object
271
-     *
272
-     * @return array
273
-     */
274
-    public function getAttributes() : array
275
-    {
276
-        return $this->attributes;
277
-    }
278
-
279
-    /**
280
-     * Set the domain class attributes
281
-     *
282
-     * @param array $attributeNames
283
-     */
284
-    public function setAttributes(array $attributeNames)
285
-    {
286
-        $this->attributes = $attributeNames;
287
-    }
288
-
289
-    /**  
290
-     * Return true if the Entity has an 'attributes' array property
291
-     * 
292
-     * @return boolean
293
-     */
294
-    public function usesAttributesArray() : bool
295
-    {
296
-        return $this->arrayName === null ? false : true;
297
-    }
298
-
299
-    /**  
300
-     * Return the name of the Entity's attributes property
301
-     * 
302
-     * @return string|null
303
-     */
304
-    public function getAttributesArrayName()
305
-    {
306
-        return $this->arrayName;
307
-    }
308
-
309
-    /**
310
-     * Get all the attribute names for the class, including relationships, embeddables and primary key.
311
-     *
312
-     * @return array
313
-     */
314
-    public function getCompiledAttributes() : array
315
-    {
316
-        $key = $this->getKeyName();
317
-
318
-        $embeddables = array_keys($this->getEmbeddables());
319
-
320
-        $relationships = $this->getRelationships();
321
-
322
-        $attributes = $this->getAttributes();
323
-
324
-        return array_merge([$key], $embeddables, $relationships, $attributes);
325
-    }
326
-
327
-    /**
328
-     * Set the date format to use with the current database connection
329
-     *
330
-     * @param string $format
331
-     */
332
-    public function setDateFormat($format)
333
-    {
334
-        $this->dateFormat = $format;
335
-    }
336
-
337
-    /**
338
-     * Get the date format to use with the current database connection
339
-     *
340
-     *  @return string
341
-     */
342
-    public function getDateFormat() : string
343
-    {
344
-        return $this->dateFormat;
345
-    }
346
-
347
-    /**
348
-     * Set the Driver for this mapping
349
-     *
350
-     * @param string $driver
351
-     */
352
-    public function setDriver($driver)
353
-    {
354
-        $this->driver = $driver;
355
-    }
356
-
357
-    /**
358
-     * Get the Driver for this mapping.
359
-     *
360
-     * @return string
361
-     */
362
-    public function getDriver() : string
363
-    {
364
-        return $this->driver;
365
-    }
366
-
367
-    /**
368
-     * Set the db connection to use on the table
369
-     *
370
-     * @param $connection
371
-     */
372
-    public function setConnection($connection)
373
-    {
374
-        $this->connection = $connection;
375
-    }
376
-
377
-    /**
378
-     * Get the Database connection the Entity is stored on.
379
-     *
380
-     * @return string | null
381
-     */
382
-    public function getConnection()
383
-    {
384
-        return $this->connection;
385
-    }
386
-
387
-    /**
388
-     * Get the table associated with the entity.
389
-     *
390
-     * @return string
391
-     */
392
-    public function getTable() : string
393
-    {
394
-        if (!is_null($this->table)) {
395
-            return $this->table;
396
-        }
397
-
398
-        return str_replace('\\', '', snake_case(str_plural(class_basename($this->getClass()))));
399
-    }
400
-
401
-    /**
402
-     * Set the database table name
403
-     *
404
-     * @param  string $table
405
-     */
406
-    public function setTable($table)
407
-    {
408
-        $this->table = $table;
409
-    }
410
-
411
-    /**
412
-     * Get the pgSql sequence name
413
-     *
414
-     * @return string
415
-     */
416
-    public function getSequence() : string
417
-    {
418
-        if (!is_null($this->sequence)) {
419
-            return $this->sequence;
420
-        } else {
421
-            return $this->getTable() . '_id_seq';
422
-        }
423
-    }
424
-
425
-    /**
426
-     * Get the custom entity class
427
-     *
428
-     * @return string namespaced class name
429
-     */
430
-    public function getClass() : string
431
-    {
432
-        return isset($this->class) ? $this->class : null;
433
-    }
434
-
435
-    /**
436
-     * Set the custom entity class
437
-     *
438
-     * @param string $class namespaced class name
439
-     */
440
-    public function setClass($class)
441
-    {
442
-        $this->class = $class;
443
-    }
444
-
445
-    /**
446
-     * Get the embedded Value Objects
447
-     *
448
-     * @return array
449
-     */
450
-    public function getEmbeddables() : array
451
-    {
452
-        return $this->embeddables;
453
-    }
454
-
455
-    /**  
456
-     * Return attributes that should be mapped to class properties
457
-     * 
458
-     * @return array
459
-     */
460
-    public function getProperties() : array
461
-    {
462
-        return $this->properties;
463
-    }
464
-
465
-    /**  
466
-     * Return the array property in which will be mapped all attributes
467
-     * that are not mapped to class properties.
468
-     * 
469
-     * @return string
470
-     */
471
-    public function getAttributesPropertyName() : string
472
-    {
473
-
474
-    }
475
-
476
-    /**
477
-     * Set the embedded Value Objects
478
-     *
479
-     * @param array $embeddables
480
-     */
481
-    public function setEmbeddables(array $embeddables)
482
-    {
483
-        $this->embeddables = $embeddables;
484
-    }
485
-
486
-    /**
487
-     * Get the relationships to map on a custom domain
488
-     * class.
489
-     *
490
-     * @return array
491
-     */
492
-    public function getRelationships() : array
493
-    {
494
-        return $this->relationships;
495
-    }
496
-
497
-    /**  
498
-     * Get the relationships that will not have a proxy
499
-     * set on them
500
-     * 
501
-     * @return array
502
-     */
503
-    public function getRelationshipsWithoutProxy() : array
504
-    {
505
-        return $this->nonProxyRelationships;
506
-    }
507
-
508
-    /**
509
-     * Relationships of the Entity type
510
-     *
511
-     * @return array
512
-     */
513
-    public function getSingleRelationships() : array
514
-    {
515
-        return $this->singleRelations;
516
-    }
517
-
518
-    /**
519
-     * Relationships of type Collection
520
-     *
521
-     * @return array
522
-     */
523
-    public function getManyRelationships() : array
524
-    {
525
-        return $this->manyRelations;
526
-    }
527
-
528
-    /**
529
-     * Relationships with foreign key in the mapped entity record.
530
-     *
531
-     * @return array
532
-     */
533
-    public function getLocalRelationships() : array
534
-    {
535
-        return $this->localRelations;
536
-    }
537
-
538
-    /**  
539
-     * Return the local keys associated to the relationship
540
-     * 
541
-     * @param  string $relation
542
-     * @return string | array | null
543
-     */
544
-    public function getLocalKeys($relation)
545
-    {
546
-        return isset($this->localForeignKeys[$relation]) ? $this->localForeignKeys[$relation] : null;
547
-    }
548
-
549
-    /**
550
-     * Relationships with foreign key in the related Entity record
551
-     *
552
-     * @return array
553
-     */
554
-    public function getForeignRelationships() : array
555
-    {
556
-        return $this->foreignRelations;
557
-    }
558
-
559
-    /**
560
-     * Relationships which keys are stored in a pivot record
561
-     *
562
-     * @return array
563
-     */
564
-    public function getPivotRelationships() : array
565
-    {
566
-        return $this->pivotRelations;
567
-    }
568
-
569
-    /**  
570
-     * Get the targetted type for a relationship. Return null if polymorphic
571
-     * 
572
-     * @param  string  $relation
573
-     * @return string | null
574
-     */
575
-    public function getTargettedClass($relation)
576
-    {
577
-        return $this->relatedClasses[$relation];
578
-    }
579
-
580
-    /**
581
-     * Add a Dynamic Relationship method at runtime. This has to be done
582
-     * by hooking the 'initializing' event, before entityMap is initialized.
583
-     *
584
-     * @param string  $name         Relation name
585
-     * @param \Closure $relationship
586
-     *
587
-     * @return void
588
-     */
589
-    public function addRelationshipMethod($name, \Closure $relationship)
590
-    {
591
-        $this->dynamicRelationships[$name] = $relationship;
592
-    }
593
-
594
-    /**
595
-     * Get the dynamic relationship method names.
596
-     *
597
-     * @return array
598
-     */
599
-    public function getDynamicRelationships() : array
600
-    {
601
-        return array_keys($this->dynamicRelationships);
602
-    }
603
-
604
-    /**
605
-     * Get the relationships that have to be eager loaded
606
-     * on each request.
607
-     *
608
-     * @return array
609
-     */
610
-    public function getEagerloadedRelationships() : array
611
-    {
612
-        return $this->with;
613
-    }
614
-
615
-    /**
616
-     * Get the primary key attribute for the entity.
617
-     *
618
-     * @return string
619
-     */
620
-    public function getKeyName() : string
621
-    {
622
-        return $this->primaryKey;
623
-    }
624
-
625
-    /**
626
-     * Set the primary key for the entity.
627
-     *
628
-     * @param $key
629
-     * @return void
630
-     */
631
-    public function setKeyName($key)
632
-    {
633
-        $this->primaryKey = $key;
634
-    }
635
-
636
-    /**
637
-     * Get the table qualified key name.
638
-     *
639
-     * @return string
640
-     */
641
-    public function getQualifiedKeyName() : string
642
-    {
643
-        return $this->getTable() . '.' . $this->getKeyName();
644
-    }
645
-
646
-    /**
647
-     * Get the number of models to return per page.
648
-     *
649
-     * @return int
650
-     */
651
-    public function getPerPage() : int
652
-    {
653
-        return $this->perPage;
654
-    }
655
-
656
-    /**
657
-     * Set the number of models to return per page.
658
-     *
659
-     * @param  int $perPage
660
-     * @return void
661
-     */
662
-    public function setPerPage($perPage)
663
-    {
664
-        $this->perPage = $perPage;
665
-    }
666
-
667
-    /**
668
-     * Determine if the entity uses get.
669
-     *
670
-     * @return bool
671
-     */
672
-    public function usesTimestamps() : bool
673
-    {
674
-        return $this->timestamps;
675
-    }
676
-
677
-    /**
678
-     * Determine if the entity uses soft deletes
679
-     *
680
-     * @return bool
681
-     */
682
-    public function usesSoftDeletes() : bool
683
-    {
684
-        return $this->softDeletes;
685
-    }
686
-
687
-    /**
688
-     * Get the 'created_at' column name
689
-     *
690
-     * @return string
691
-     */
692
-    public function getCreatedAtColumn() : string
693
-    {
694
-        return $this->createdAtColumn;
695
-    }
696
-
697
-    /**
698
-     * Get the 'updated_at' column name
699
-     *
700
-     * @return string
701
-     */
702
-    public function getUpdatedAtColumn() : string
703
-    {
704
-        return $this->updatedAtColumn;
705
-    }
706
-
707
-    /**
708
-     * Get the deleted_at column
709
-     *
710
-     * @return string
711
-     */
712
-    public function getQualifiedDeletedAtColumn() : string
713
-    {
714
-        return $this->deletedAtColumn;
715
-    }
716
-
717
-    /**
718
-     * Get the default foreign key name for the model.
719
-     *
720
-     * @return string
721
-     */
722
-    public function getForeignKey() : string
723
-    {
724
-        return snake_case(class_basename($this->getClass())) . '_id';
725
-    }
726
-
727
-    /**
728
-     * Return the inheritance type used by the entity.
729
-     *
730
-     * @return string|null
731
-     */
732
-    public function getInheritanceType()
733
-    {
734
-        return $this->inheritanceType;
735
-    }
736
-
737
-    /**
738
-     * Return the discriminator column name on the entity that's
739
-     * used for table inheritance.
740
-     *
741
-     * @return string
742
-     */
743
-    public function getDiscriminatorColumn() : string
744
-    {
745
-        return $this->discriminatorColumn;
746
-    }
747
-
748
-    /**
749
-     * Return the mapping of discriminator column values to
750
-     * entity class names that are used for table inheritance.
751
-     *
752
-     * @return array
753
-     */
754
-    public function getDiscriminatorColumnMap() : array
755
-    {
756
-        return $this->discriminatorColumnMap;
757
-    }
758
-
759
-    /**
760
-     * Return true if the entity should be instanciated using
761
-     * the IoC Container
762
-     * 
763
-     * @return boolean
764
-     */
765
-    public function useDependencyInjection() : bool
766
-    {
767
-        return $this->dependencyInjection;
768
-    }
769
-
770
-    /**  
771
-     * Add a single relation method name once
772
-     * 
773
-     * @param string  $relation
774
-     */
775
-    protected function addSingleRelation($relation)
776
-    {
777
-        if(! in_array($relation, $this->singleRelations)) {
778
-            $this->singleRelations[] = $relation;
779
-        }
780
-    }
781
-
782
-    /**  
783
-     * Add a foreign relation method name once
784
-     * 
785
-     * @param string  $relation
786
-     */
787
-    protected function addForeignRelation($relation)
788
-    {
789
-        if(! in_array($relation, $this->foreignRelations)) {
790
-            $this->foreignRelations[] = $relation;
791
-        }
792
-    }
793
-
794
-    /**  
795
-     * Add a non proxy relation method name once
796
-     * 
797
-     * @param string  $relation
798
-     */
799
-    protected function addNonProxyRelation($relation)
800
-    {
801
-        if(! in_array($relation, $this->nonProxyRelationships)) {
802
-            $this->nonProxyRelationships[] = $relation;
803
-        }
804
-    }
805
-
806
-    /**  
807
-     * Add a local relation method name once
808
-     * 
809
-     * @param string  $relation
810
-     */
811
-    protected function addLocalRelation($relation)
812
-    {
813
-        if(! in_array($relation, $this->localRelations)) {
814
-            $this->localRelations[] = $relation;
815
-        }
816
-    }
817
-
818
-     /**  
819
-     * Add a many relation method name once
820
-     * 
821
-     * @param string  $relation
822
-     */
823
-    protected function addManyRelation($relation)
824
-    {
825
-        if(! in_array($relation, $this->manyRelations)) {
826
-            $this->manyRelations[] = $relation;
827
-        }
828
-    }
829
-
830
-     /**  
831
-     * Add a pivot relation method name once
832
-     * 
833
-     * @param string  $relation
834
-     */
835
-    protected function addPivotRelation($relation)
836
-    {
837
-        if(! in_array($relation, $this->pivotRelations)) {
838
-            $this->pivotRelations[] = $relation;
839
-        }
840
-    }
841
-
842
-    /**
843
-     * Define a one-to-one relationship.
844
-     *
845
-     * @param  mixed  $entity
846
-     * @param  string $related entity class
847
-     * @param  string $foreignKey
848
-     * @param  string $localKey
849
-     * @throws MappingException
850
-     * @return \Analogue\ORM\Relationships\HasOne
851
-     */
852
-    public function hasOne($entity, $related, $foreignKey = null, $localKey = null)
853
-    {
854
-        $foreignKey = $foreignKey ?: $this->getForeignKey();
855
-
856
-        $relatedMapper = Manager::getInstance()->mapper($related);
857
-
858
-        $relatedMap = $relatedMapper->getEntityMap();
859
-
860
-        $localKey = $localKey ?: $this->getKeyName();
861
-
862
-        // Add the relation to the definition in map
863
-        list(, $caller) = debug_backtrace(false);
864
-        $relation = $caller['function'];
865
-        $this->relatedClasses[$relation] = $related;
26
+	/**
27
+	 * The mapping driver to use with this entity
28
+	 *
29
+	 * @var  string
30
+	 */
31
+	protected $driver = 'illuminate';
32
+
33
+	/**
34
+	 * The Database Connection name for the model.
35
+	 *
36
+	 * @var string
37
+	 */
38
+	protected $connection;
39
+
40
+	/**
41
+	 * The table associated with the entity.
42
+	 *
43
+	 * @var string|null
44
+	 */
45
+	protected $table = null;
46
+
47
+	/**
48
+	 * The primary key for the model.
49
+	 *
50
+	 * @var string
51
+	 */
52
+	protected $primaryKey = 'id';
53
+
54
+	/**
55
+	 * Name of the entity's array property that should
56
+	 * contain the attributes. 
57
+	 * If set to null, analogue will only hydrate object's properties
58
+	 * 
59
+	 * @var string|null
60
+	 */
61
+	protected $arrayName = 'attributes';
62
+
63
+	/**
64
+	 * Array containing the list of database columns to be mapped
65
+	 * in the attributes array of the entity. 
66
+	 *
67
+	 * @var array
68
+	 */
69
+	protected $attributes = [];
70
+
71
+	/**
72
+	 * Array containing the list of database columns to be mapped
73
+	 * to the entity's class properties. 
74
+	 *
75
+	 * @var array
76
+	 */
77
+	protected $properties = [];
78
+
79
+	/**
80
+	 * The Custom Domain Class to use with this mapping
81
+	 *
82
+	 * @var string|null
83
+	 */
84
+	protected $class = null;
85
+
86
+	/**
87
+	 * Embedded Value Objects
88
+	 * 
89
+	 * @var array
90
+	 */
91
+	protected $embeddables = [];
92
+
93
+	/**
94
+	 * Determine the relationships method used on the entity.
95
+	 * If not set, mapper will autodetect them
96
+	 *
97
+	 * @var array
98
+	 */
99
+	private $relationships = [];
100
+
101
+	/**
102
+	 * Relationships that should be treated as collection.
103
+	 *
104
+	 * @var array
105
+	 */
106
+	private $manyRelations = [];
107
+
108
+	/**
109
+	 * Relationships that should be treated as single entity.
110
+	 *
111
+	 * @var array
112
+	 */
113
+	private $singleRelations = [];
114
+
115
+	/**
116
+	 * Relationships for which the key is stored in the Entity itself
117
+	 *
118
+	 * @var array
119
+	 */
120
+	private $localRelations = [];
121
+
122
+	/** 
123
+	 * List of local keys associated to local relation methods
124
+	 * 
125
+	 * @var array
126
+	 */
127
+	private $localForeignKeys = [];
128
+
129
+	/**
130
+	 * Relationships for which the key is stored in the Related Entity
131
+	 *
132
+	 * @var array
133
+	 */
134
+	private $foreignRelations = [];
135
+
136
+	/**
137
+	 * Relationships which use a pivot record.
138
+	 *
139
+	 * @var array
140
+	 */
141
+	private $pivotRelations = [];
142
+
143
+	/**
144
+	 * Dynamic relationships
145
+	 *
146
+	 * @var array
147
+	 */
148
+	private $dynamicRelationships = [];
149
+
150
+	/**
151
+	 * Targetted class for the relationship method. value is set to `null` for
152
+	 * polymorphic relations. 
153
+	 * 
154
+	 * @var array
155
+	 */
156
+	private $relatedClasses = [];
157
+
158
+	/** 
159
+	 * Some relation methods like embedded objects, or HasOne and MorphOne,
160
+	 * will never have a proxy loaded on them. 
161
+	 * 
162
+	 * @var  array
163
+	 */
164
+	private $nonProxyRelationships = [];
165
+
166
+	/**
167
+	 * The number of models to return for pagination.
168
+	 *
169
+	 * @var int
170
+	 */
171
+	protected $perPage = 15;
172
+
173
+	/**
174
+	 * The relations to eager load on every query.
175
+	 *
176
+	 * @var array
177
+	 */
178
+	protected $with = [];
179
+
180
+	/**
181
+	 * The class name to be used in polymorphic relations.
182
+	 *
183
+	 * @var string
184
+	 */
185
+	protected $morphClass;
186
+
187
+	/**
188
+	 * Sequence name, to be used with postgreSql
189
+	 * defaults to %table_name%_id_seq
190
+	 *
191
+	 * @var string|null
192
+	 */
193
+	protected $sequence = null;
194
+
195
+	/**
196
+	 * Indicates if the entity should be timestamped.
197
+	 *
198
+	 * @var bool
199
+	 */
200
+	public $timestamps = false;
201
+
202
+	/**
203
+	 * The name of the "created at" column.
204
+	 *
205
+	 * @var string
206
+	 */
207
+	protected $createdAtColumn = 'created_at';
208
+
209
+	/**
210
+	 * The name of the "updated at" column.
211
+	 *
212
+	 * @var string
213
+	 */
214
+	protected $updatedAtColumn = 'updated_at';
215
+
216
+	/**
217
+	 * Indicates if the entity uses softdeletes
218
+	 *
219
+	 * @var boolean
220
+	 */
221
+	public $softDeletes = false;
222
+
223
+	/**
224
+	 * The name of the "deleted at" column.
225
+	 *
226
+	 * @var string
227
+	 */
228
+	protected $deletedAtColumn = 'deleted_at';
229
+
230
+	/**
231
+	 * The date format to use with the current database connection
232
+	 *
233
+	 * @var string
234
+	 */
235
+	protected $dateFormat;
236
+
237
+	/**
238
+	 * Set this property to true if the entity should be instantiated
239
+	 * using the IoC Container
240
+	 * 
241
+	 * @var boolean
242
+	 */
243
+	protected $dependencyInjection = false;
244
+
245
+	/**
246
+	 * Set the usage of inheritance, possible values are :
247
+	 * "single_table"
248
+	 * null
249
+	 * 
250
+	 * @var string | null
251
+	 */
252
+	protected $inheritanceType = null;
253
+
254
+	/**
255
+	 * Discriminator column name
256
+	 * 
257
+	 * @var string
258
+	 */
259
+	protected $discriminatorColumn = "type";
260
+
261
+	/**
262
+	 * Allow using a string to define which entity type should be instantiated.
263
+	 * If not set, analogue will uses entity's FQDN
264
+	 * 
265
+	 * @var array
266
+	 */
267
+	protected $discriminatorColumnMap = [];
268
+
269
+	/**
270
+	 * Return Domain class attributes, useful when mapping to a Plain PHP Object
271
+	 *
272
+	 * @return array
273
+	 */
274
+	public function getAttributes() : array
275
+	{
276
+		return $this->attributes;
277
+	}
278
+
279
+	/**
280
+	 * Set the domain class attributes
281
+	 *
282
+	 * @param array $attributeNames
283
+	 */
284
+	public function setAttributes(array $attributeNames)
285
+	{
286
+		$this->attributes = $attributeNames;
287
+	}
288
+
289
+	/**  
290
+	 * Return true if the Entity has an 'attributes' array property
291
+	 * 
292
+	 * @return boolean
293
+	 */
294
+	public function usesAttributesArray() : bool
295
+	{
296
+		return $this->arrayName === null ? false : true;
297
+	}
298
+
299
+	/**  
300
+	 * Return the name of the Entity's attributes property
301
+	 * 
302
+	 * @return string|null
303
+	 */
304
+	public function getAttributesArrayName()
305
+	{
306
+		return $this->arrayName;
307
+	}
308
+
309
+	/**
310
+	 * Get all the attribute names for the class, including relationships, embeddables and primary key.
311
+	 *
312
+	 * @return array
313
+	 */
314
+	public function getCompiledAttributes() : array
315
+	{
316
+		$key = $this->getKeyName();
317
+
318
+		$embeddables = array_keys($this->getEmbeddables());
319
+
320
+		$relationships = $this->getRelationships();
321
+
322
+		$attributes = $this->getAttributes();
323
+
324
+		return array_merge([$key], $embeddables, $relationships, $attributes);
325
+	}
326
+
327
+	/**
328
+	 * Set the date format to use with the current database connection
329
+	 *
330
+	 * @param string $format
331
+	 */
332
+	public function setDateFormat($format)
333
+	{
334
+		$this->dateFormat = $format;
335
+	}
336
+
337
+	/**
338
+	 * Get the date format to use with the current database connection
339
+	 *
340
+	 *  @return string
341
+	 */
342
+	public function getDateFormat() : string
343
+	{
344
+		return $this->dateFormat;
345
+	}
346
+
347
+	/**
348
+	 * Set the Driver for this mapping
349
+	 *
350
+	 * @param string $driver
351
+	 */
352
+	public function setDriver($driver)
353
+	{
354
+		$this->driver = $driver;
355
+	}
356
+
357
+	/**
358
+	 * Get the Driver for this mapping.
359
+	 *
360
+	 * @return string
361
+	 */
362
+	public function getDriver() : string
363
+	{
364
+		return $this->driver;
365
+	}
366
+
367
+	/**
368
+	 * Set the db connection to use on the table
369
+	 *
370
+	 * @param $connection
371
+	 */
372
+	public function setConnection($connection)
373
+	{
374
+		$this->connection = $connection;
375
+	}
376
+
377
+	/**
378
+	 * Get the Database connection the Entity is stored on.
379
+	 *
380
+	 * @return string | null
381
+	 */
382
+	public function getConnection()
383
+	{
384
+		return $this->connection;
385
+	}
386
+
387
+	/**
388
+	 * Get the table associated with the entity.
389
+	 *
390
+	 * @return string
391
+	 */
392
+	public function getTable() : string
393
+	{
394
+		if (!is_null($this->table)) {
395
+			return $this->table;
396
+		}
397
+
398
+		return str_replace('\\', '', snake_case(str_plural(class_basename($this->getClass()))));
399
+	}
400
+
401
+	/**
402
+	 * Set the database table name
403
+	 *
404
+	 * @param  string $table
405
+	 */
406
+	public function setTable($table)
407
+	{
408
+		$this->table = $table;
409
+	}
410
+
411
+	/**
412
+	 * Get the pgSql sequence name
413
+	 *
414
+	 * @return string
415
+	 */
416
+	public function getSequence() : string
417
+	{
418
+		if (!is_null($this->sequence)) {
419
+			return $this->sequence;
420
+		} else {
421
+			return $this->getTable() . '_id_seq';
422
+		}
423
+	}
424
+
425
+	/**
426
+	 * Get the custom entity class
427
+	 *
428
+	 * @return string namespaced class name
429
+	 */
430
+	public function getClass() : string
431
+	{
432
+		return isset($this->class) ? $this->class : null;
433
+	}
434
+
435
+	/**
436
+	 * Set the custom entity class
437
+	 *
438
+	 * @param string $class namespaced class name
439
+	 */
440
+	public function setClass($class)
441
+	{
442
+		$this->class = $class;
443
+	}
444
+
445
+	/**
446
+	 * Get the embedded Value Objects
447
+	 *
448
+	 * @return array
449
+	 */
450
+	public function getEmbeddables() : array
451
+	{
452
+		return $this->embeddables;
453
+	}
454
+
455
+	/**  
456
+	 * Return attributes that should be mapped to class properties
457
+	 * 
458
+	 * @return array
459
+	 */
460
+	public function getProperties() : array
461
+	{
462
+		return $this->properties;
463
+	}
464
+
465
+	/**  
466
+	 * Return the array property in which will be mapped all attributes
467
+	 * that are not mapped to class properties.
468
+	 * 
469
+	 * @return string
470
+	 */
471
+	public function getAttributesPropertyName() : string
472
+	{
473
+
474
+	}
475
+
476
+	/**
477
+	 * Set the embedded Value Objects
478
+	 *
479
+	 * @param array $embeddables
480
+	 */
481
+	public function setEmbeddables(array $embeddables)
482
+	{
483
+		$this->embeddables = $embeddables;
484
+	}
485
+
486
+	/**
487
+	 * Get the relationships to map on a custom domain
488
+	 * class.
489
+	 *
490
+	 * @return array
491
+	 */
492
+	public function getRelationships() : array
493
+	{
494
+		return $this->relationships;
495
+	}
496
+
497
+	/**  
498
+	 * Get the relationships that will not have a proxy
499
+	 * set on them
500
+	 * 
501
+	 * @return array
502
+	 */
503
+	public function getRelationshipsWithoutProxy() : array
504
+	{
505
+		return $this->nonProxyRelationships;
506
+	}
507
+
508
+	/**
509
+	 * Relationships of the Entity type
510
+	 *
511
+	 * @return array
512
+	 */
513
+	public function getSingleRelationships() : array
514
+	{
515
+		return $this->singleRelations;
516
+	}
517
+
518
+	/**
519
+	 * Relationships of type Collection
520
+	 *
521
+	 * @return array
522
+	 */
523
+	public function getManyRelationships() : array
524
+	{
525
+		return $this->manyRelations;
526
+	}
527
+
528
+	/**
529
+	 * Relationships with foreign key in the mapped entity record.
530
+	 *
531
+	 * @return array
532
+	 */
533
+	public function getLocalRelationships() : array
534
+	{
535
+		return $this->localRelations;
536
+	}
537
+
538
+	/**  
539
+	 * Return the local keys associated to the relationship
540
+	 * 
541
+	 * @param  string $relation
542
+	 * @return string | array | null
543
+	 */
544
+	public function getLocalKeys($relation)
545
+	{
546
+		return isset($this->localForeignKeys[$relation]) ? $this->localForeignKeys[$relation] : null;
547
+	}
548
+
549
+	/**
550
+	 * Relationships with foreign key in the related Entity record
551
+	 *
552
+	 * @return array
553
+	 */
554
+	public function getForeignRelationships() : array
555
+	{
556
+		return $this->foreignRelations;
557
+	}
558
+
559
+	/**
560
+	 * Relationships which keys are stored in a pivot record
561
+	 *
562
+	 * @return array
563
+	 */
564
+	public function getPivotRelationships() : array
565
+	{
566
+		return $this->pivotRelations;
567
+	}
568
+
569
+	/**  
570
+	 * Get the targetted type for a relationship. Return null if polymorphic
571
+	 * 
572
+	 * @param  string  $relation
573
+	 * @return string | null
574
+	 */
575
+	public function getTargettedClass($relation)
576
+	{
577
+		return $this->relatedClasses[$relation];
578
+	}
579
+
580
+	/**
581
+	 * Add a Dynamic Relationship method at runtime. This has to be done
582
+	 * by hooking the 'initializing' event, before entityMap is initialized.
583
+	 *
584
+	 * @param string  $name         Relation name
585
+	 * @param \Closure $relationship
586
+	 *
587
+	 * @return void
588
+	 */
589
+	public function addRelationshipMethod($name, \Closure $relationship)
590
+	{
591
+		$this->dynamicRelationships[$name] = $relationship;
592
+	}
593
+
594
+	/**
595
+	 * Get the dynamic relationship method names.
596
+	 *
597
+	 * @return array
598
+	 */
599
+	public function getDynamicRelationships() : array
600
+	{
601
+		return array_keys($this->dynamicRelationships);
602
+	}
603
+
604
+	/**
605
+	 * Get the relationships that have to be eager loaded
606
+	 * on each request.
607
+	 *
608
+	 * @return array
609
+	 */
610
+	public function getEagerloadedRelationships() : array
611
+	{
612
+		return $this->with;
613
+	}
614
+
615
+	/**
616
+	 * Get the primary key attribute for the entity.
617
+	 *
618
+	 * @return string
619
+	 */
620
+	public function getKeyName() : string
621
+	{
622
+		return $this->primaryKey;
623
+	}
624
+
625
+	/**
626
+	 * Set the primary key for the entity.
627
+	 *
628
+	 * @param $key
629
+	 * @return void
630
+	 */
631
+	public function setKeyName($key)
632
+	{
633
+		$this->primaryKey = $key;
634
+	}
635
+
636
+	/**
637
+	 * Get the table qualified key name.
638
+	 *
639
+	 * @return string
640
+	 */
641
+	public function getQualifiedKeyName() : string
642
+	{
643
+		return $this->getTable() . '.' . $this->getKeyName();
644
+	}
645
+
646
+	/**
647
+	 * Get the number of models to return per page.
648
+	 *
649
+	 * @return int
650
+	 */
651
+	public function getPerPage() : int
652
+	{
653
+		return $this->perPage;
654
+	}
655
+
656
+	/**
657
+	 * Set the number of models to return per page.
658
+	 *
659
+	 * @param  int $perPage
660
+	 * @return void
661
+	 */
662
+	public function setPerPage($perPage)
663
+	{
664
+		$this->perPage = $perPage;
665
+	}
666
+
667
+	/**
668
+	 * Determine if the entity uses get.
669
+	 *
670
+	 * @return bool
671
+	 */
672
+	public function usesTimestamps() : bool
673
+	{
674
+		return $this->timestamps;
675
+	}
676
+
677
+	/**
678
+	 * Determine if the entity uses soft deletes
679
+	 *
680
+	 * @return bool
681
+	 */
682
+	public function usesSoftDeletes() : bool
683
+	{
684
+		return $this->softDeletes;
685
+	}
686
+
687
+	/**
688
+	 * Get the 'created_at' column name
689
+	 *
690
+	 * @return string
691
+	 */
692
+	public function getCreatedAtColumn() : string
693
+	{
694
+		return $this->createdAtColumn;
695
+	}
696
+
697
+	/**
698
+	 * Get the 'updated_at' column name
699
+	 *
700
+	 * @return string
701
+	 */
702
+	public function getUpdatedAtColumn() : string
703
+	{
704
+		return $this->updatedAtColumn;
705
+	}
706
+
707
+	/**
708
+	 * Get the deleted_at column
709
+	 *
710
+	 * @return string
711
+	 */
712
+	public function getQualifiedDeletedAtColumn() : string
713
+	{
714
+		return $this->deletedAtColumn;
715
+	}
716
+
717
+	/**
718
+	 * Get the default foreign key name for the model.
719
+	 *
720
+	 * @return string
721
+	 */
722
+	public function getForeignKey() : string
723
+	{
724
+		return snake_case(class_basename($this->getClass())) . '_id';
725
+	}
726
+
727
+	/**
728
+	 * Return the inheritance type used by the entity.
729
+	 *
730
+	 * @return string|null
731
+	 */
732
+	public function getInheritanceType()
733
+	{
734
+		return $this->inheritanceType;
735
+	}
736
+
737
+	/**
738
+	 * Return the discriminator column name on the entity that's
739
+	 * used for table inheritance.
740
+	 *
741
+	 * @return string
742
+	 */
743
+	public function getDiscriminatorColumn() : string
744
+	{
745
+		return $this->discriminatorColumn;
746
+	}
747
+
748
+	/**
749
+	 * Return the mapping of discriminator column values to
750
+	 * entity class names that are used for table inheritance.
751
+	 *
752
+	 * @return array
753
+	 */
754
+	public function getDiscriminatorColumnMap() : array
755
+	{
756
+		return $this->discriminatorColumnMap;
757
+	}
758
+
759
+	/**
760
+	 * Return true if the entity should be instanciated using
761
+	 * the IoC Container
762
+	 * 
763
+	 * @return boolean
764
+	 */
765
+	public function useDependencyInjection() : bool
766
+	{
767
+		return $this->dependencyInjection;
768
+	}
769
+
770
+	/**  
771
+	 * Add a single relation method name once
772
+	 * 
773
+	 * @param string  $relation
774
+	 */
775
+	protected function addSingleRelation($relation)
776
+	{
777
+		if(! in_array($relation, $this->singleRelations)) {
778
+			$this->singleRelations[] = $relation;
779
+		}
780
+	}
781
+
782
+	/**  
783
+	 * Add a foreign relation method name once
784
+	 * 
785
+	 * @param string  $relation
786
+	 */
787
+	protected function addForeignRelation($relation)
788
+	{
789
+		if(! in_array($relation, $this->foreignRelations)) {
790
+			$this->foreignRelations[] = $relation;
791
+		}
792
+	}
793
+
794
+	/**  
795
+	 * Add a non proxy relation method name once
796
+	 * 
797
+	 * @param string  $relation
798
+	 */
799
+	protected function addNonProxyRelation($relation)
800
+	{
801
+		if(! in_array($relation, $this->nonProxyRelationships)) {
802
+			$this->nonProxyRelationships[] = $relation;
803
+		}
804
+	}
805
+
806
+	/**  
807
+	 * Add a local relation method name once
808
+	 * 
809
+	 * @param string  $relation
810
+	 */
811
+	protected function addLocalRelation($relation)
812
+	{
813
+		if(! in_array($relation, $this->localRelations)) {
814
+			$this->localRelations[] = $relation;
815
+		}
816
+	}
817
+
818
+	 /**  
819
+	  * Add a many relation method name once
820
+	  * 
821
+	  * @param string  $relation
822
+	  */
823
+	protected function addManyRelation($relation)
824
+	{
825
+		if(! in_array($relation, $this->manyRelations)) {
826
+			$this->manyRelations[] = $relation;
827
+		}
828
+	}
829
+
830
+	 /**  
831
+	  * Add a pivot relation method name once
832
+	  * 
833
+	  * @param string  $relation
834
+	  */
835
+	protected function addPivotRelation($relation)
836
+	{
837
+		if(! in_array($relation, $this->pivotRelations)) {
838
+			$this->pivotRelations[] = $relation;
839
+		}
840
+	}
841
+
842
+	/**
843
+	 * Define a one-to-one relationship.
844
+	 *
845
+	 * @param  mixed  $entity
846
+	 * @param  string $related entity class
847
+	 * @param  string $foreignKey
848
+	 * @param  string $localKey
849
+	 * @throws MappingException
850
+	 * @return \Analogue\ORM\Relationships\HasOne
851
+	 */
852
+	public function hasOne($entity, $related, $foreignKey = null, $localKey = null)
853
+	{
854
+		$foreignKey = $foreignKey ?: $this->getForeignKey();
855
+
856
+		$relatedMapper = Manager::getInstance()->mapper($related);
857
+
858
+		$relatedMap = $relatedMapper->getEntityMap();
859
+
860
+		$localKey = $localKey ?: $this->getKeyName();
861
+
862
+		// Add the relation to the definition in map
863
+		list(, $caller) = debug_backtrace(false);
864
+		$relation = $caller['function'];
865
+		$this->relatedClasses[$relation] = $related;
866 866
         
867
-        $this->addSingleRelation($relation);
868
-        $this->addForeignRelation($relation);
869
-        $this->addNonProxyRelation($relation);
870
-
871
-        // This relationship will always be eager loaded, as proxying it would
872
-        // mean having an object that doesn't actually exists.
873
-        if(! in_array($relation, $this->with)) {
874
-            $this->with[] = $relation;
875
-        }
876
-
877
-        return new HasOne($relatedMapper, $entity, $relatedMap->getTable() . '.' . $foreignKey, $localKey);
878
-    }
879
-
880
-    /**
881
-     * Define a polymorphic one-to-one relationship.
882
-     *
883
-     * @param  mixed       $entity
884
-     * @param  string      $related
885
-     * @param  string      $name
886
-     * @param  string|null $type
887
-     * @param  string|null $id
888
-     * @param  string|null $localKey
889
-     * @throws MappingException
890
-     * @return \Analogue\ORM\Relationships\MorphOne
891
-     */
892
-    public function morphOne($entity, $related, $name, $type = null, $id = null, $localKey = null)
893
-    {
894
-        list($type, $id) = $this->getMorphs($name, $type, $id);
895
-
896
-        $localKey = $localKey ?: $this->getKeyName();
897
-
898
-        $relatedMapper = Manager::getInstance()->mapper($related);
899
-
900
-        $table = $relatedMapper->getEntityMap()->getTable();
901
-
902
-        // Add the relation to the definition in map
903
-        list(, $caller) = debug_backtrace(false);
904
-        $relation = $caller['function'];
905
-        $this->relatedClasses[$relation] = $related;
867
+		$this->addSingleRelation($relation);
868
+		$this->addForeignRelation($relation);
869
+		$this->addNonProxyRelation($relation);
870
+
871
+		// This relationship will always be eager loaded, as proxying it would
872
+		// mean having an object that doesn't actually exists.
873
+		if(! in_array($relation, $this->with)) {
874
+			$this->with[] = $relation;
875
+		}
876
+
877
+		return new HasOne($relatedMapper, $entity, $relatedMap->getTable() . '.' . $foreignKey, $localKey);
878
+	}
879
+
880
+	/**
881
+	 * Define a polymorphic one-to-one relationship.
882
+	 *
883
+	 * @param  mixed       $entity
884
+	 * @param  string      $related
885
+	 * @param  string      $name
886
+	 * @param  string|null $type
887
+	 * @param  string|null $id
888
+	 * @param  string|null $localKey
889
+	 * @throws MappingException
890
+	 * @return \Analogue\ORM\Relationships\MorphOne
891
+	 */
892
+	public function morphOne($entity, $related, $name, $type = null, $id = null, $localKey = null)
893
+	{
894
+		list($type, $id) = $this->getMorphs($name, $type, $id);
895
+
896
+		$localKey = $localKey ?: $this->getKeyName();
897
+
898
+		$relatedMapper = Manager::getInstance()->mapper($related);
899
+
900
+		$table = $relatedMapper->getEntityMap()->getTable();
901
+
902
+		// Add the relation to the definition in map
903
+		list(, $caller) = debug_backtrace(false);
904
+		$relation = $caller['function'];
905
+		$this->relatedClasses[$relation] = $related;
906 906
         
907
-        $this->addSingleRelation($relation);
908
-        $this->addForeignRelation($relation);
909
-        $this->addNonProxyRelation($relation);
910
-
911
-        // This relationship will always be eager loaded, as proxying it would
912
-        // mean having an object that doesn't actually exists.
913
-        if(! in_array($relation, $this->with)) {
914
-            $this->with[] = $relation;
915
-        }
907
+		$this->addSingleRelation($relation);
908
+		$this->addForeignRelation($relation);
909
+		$this->addNonProxyRelation($relation);
910
+
911
+		// This relationship will always be eager loaded, as proxying it would
912
+		// mean having an object that doesn't actually exists.
913
+		if(! in_array($relation, $this->with)) {
914
+			$this->with[] = $relation;
915
+		}
916 916
         
917
-        return new MorphOne($relatedMapper, $entity, $table . '.' . $type, $table . '.' . $id, $localKey);
918
-    }
919
-
920
-    /**
921
-     * Define an inverse one-to-one or many relationship.
922
-     *
923
-     * @param  mixed       $entity
924
-     * @param  string      $related
925
-     * @param  string|null $foreignKey
926
-     * @param  string|null $otherKey
927
-     * @param  string|null $relation
928
-     * @throws MappingException
929
-     * @return \Analogue\ORM\Relationships\BelongsTo
930
-     */
931
-    public function belongsTo($entity, $related, $foreignKey = null, $otherKey = null)
932
-    {
933
-        // Add the relation to the definition in map
934
-        list(, $caller) = debug_backtrace(false);
935
-        $relation = $caller['function'];
936
-        $this->relatedClasses[$relation] = $related;
917
+		return new MorphOne($relatedMapper, $entity, $table . '.' . $type, $table . '.' . $id, $localKey);
918
+	}
919
+
920
+	/**
921
+	 * Define an inverse one-to-one or many relationship.
922
+	 *
923
+	 * @param  mixed       $entity
924
+	 * @param  string      $related
925
+	 * @param  string|null $foreignKey
926
+	 * @param  string|null $otherKey
927
+	 * @param  string|null $relation
928
+	 * @throws MappingException
929
+	 * @return \Analogue\ORM\Relationships\BelongsTo
930
+	 */
931
+	public function belongsTo($entity, $related, $foreignKey = null, $otherKey = null)
932
+	{
933
+		// Add the relation to the definition in map
934
+		list(, $caller) = debug_backtrace(false);
935
+		$relation = $caller['function'];
936
+		$this->relatedClasses[$relation] = $related;
937 937
         
938
-        $this->addSingleRelation($relation);
939
-        $this->addLocalRelation($relation);
940
-
941
-        // If no foreign key was supplied, we can use a backtrace to guess the proper
942
-        // foreign key name by using the name of the relationship function, which
943
-        // when combined with an "_id" should conventionally match the columns.
944
-        if (is_null($foreignKey)) {
945
-            $foreignKey = snake_case($relation) . '_id';
946
-        }
947
-
948
-        $this->localForeignKeys[$relation] = $foreignKey;
949
-
950
-        $relatedMapper = Manager::getInstance()->mapper($related);
951
-
952
-        $otherKey = $otherKey ?: $relatedMapper->getEntityMap()->getKeyName();
953
-
954
-        return new BelongsTo($relatedMapper, $entity, $foreignKey, $otherKey, $relation);
955
-    }
956
-
957
-    /**
958
-     * Define a polymorphic, inverse one-to-one or many relationship.
959
-     *
960
-     * @param  mixed       $entity
961
-     * @param  string|null $name
962
-     * @param  string|null $type
963
-     * @param  string|null $id
964
-     * @throws MappingException
965
-     * @return \Analogue\ORM\Relationships\MorphTo
966
-     */
967
-    public function morphTo($entity, $name = null, $type = null, $id = null)
968
-    {
969
-        // If no name is provided, we will use the backtrace to get the function name
970
-        // since that is most likely the name of the polymorphic interface. We can
971
-        // use that to get both the class and foreign key that will be utilized.
972
-        if (is_null($name)) {
973
-            list(, $caller) = debug_backtrace(false);
974
-
975
-            $name = snake_case($caller['function']);
976
-        }
977
-        $this->addSingleRelations($name);
978
-        $this->addLocalRelation($name);
979
-        $this->addForeignRelations($name);
980
-        $this->relatedClass[$relation] = null;
981
-
982
-        list($type, $id) = $this->getMorphs($name, $type, $id);
983
-
984
-        // Store the foreign key in the entity map. 
985
-        // We might want to store the (key, type) as we might need it
986
-        // to build a MorphTo proxy
987
-        $this->localForeignKeys[$name] = [
988
-            "id" => $id,
989
-            "type" => $type
990
-        ];
938
+		$this->addSingleRelation($relation);
939
+		$this->addLocalRelation($relation);
940
+
941
+		// If no foreign key was supplied, we can use a backtrace to guess the proper
942
+		// foreign key name by using the name of the relationship function, which
943
+		// when combined with an "_id" should conventionally match the columns.
944
+		if (is_null($foreignKey)) {
945
+			$foreignKey = snake_case($relation) . '_id';
946
+		}
947
+
948
+		$this->localForeignKeys[$relation] = $foreignKey;
949
+
950
+		$relatedMapper = Manager::getInstance()->mapper($related);
951
+
952
+		$otherKey = $otherKey ?: $relatedMapper->getEntityMap()->getKeyName();
953
+
954
+		return new BelongsTo($relatedMapper, $entity, $foreignKey, $otherKey, $relation);
955
+	}
956
+
957
+	/**
958
+	 * Define a polymorphic, inverse one-to-one or many relationship.
959
+	 *
960
+	 * @param  mixed       $entity
961
+	 * @param  string|null $name
962
+	 * @param  string|null $type
963
+	 * @param  string|null $id
964
+	 * @throws MappingException
965
+	 * @return \Analogue\ORM\Relationships\MorphTo
966
+	 */
967
+	public function morphTo($entity, $name = null, $type = null, $id = null)
968
+	{
969
+		// If no name is provided, we will use the backtrace to get the function name
970
+		// since that is most likely the name of the polymorphic interface. We can
971
+		// use that to get both the class and foreign key that will be utilized.
972
+		if (is_null($name)) {
973
+			list(, $caller) = debug_backtrace(false);
974
+
975
+			$name = snake_case($caller['function']);
976
+		}
977
+		$this->addSingleRelations($name);
978
+		$this->addLocalRelation($name);
979
+		$this->addForeignRelations($name);
980
+		$this->relatedClass[$relation] = null;
981
+
982
+		list($type, $id) = $this->getMorphs($name, $type, $id);
983
+
984
+		// Store the foreign key in the entity map. 
985
+		// We might want to store the (key, type) as we might need it
986
+		// to build a MorphTo proxy
987
+		$this->localForeignKeys[$name] = [
988
+			"id" => $id,
989
+			"type" => $type
990
+		];
991 991
         
992 992
 
993
-        $mapper = Manager::getInstance()->mapper(get_class($entity));
994
-
995
-        // If the type value is null it is probably safe to assume we're eager loading
996
-        // the relationship. When that is the case we will pass in a dummy query as
997
-        // there are multiple types in the morph and we can't use single queries.
998
-        $factory = new Factory;
999
-        $wrapper = $factory->make($entity);
1000
-
1001
-        if (is_null($class = $wrapper->getEntityAttribute($type))) {
1002
-            return new MorphTo(
1003
-                $mapper, $entity, $id, null, $type, $name
1004
-            );
1005
-        }
1006
-
1007
-        // If we are not eager loading the relationship we will essentially treat this
1008
-        // as a belongs-to style relationship since morph-to extends that class and
1009
-        // we will pass in the appropriate values so that it behaves as expected.
1010
-        else {
1011
-            $class = Manager::getInstance()->getInverseMorphMap($class);
1012
-            $relatedMapper = Manager::getInstance()->mapper($class);
1013
-
1014
-            $foreignKey = $relatedMapper->getEntityMap()->getKeyName();
1015
-
1016
-            return new MorphTo(
1017
-                $relatedMapper, $entity, $id, $foreignKey, $type, $name
1018
-            );
1019
-        }
1020
-    }
1021
-
1022
-    /**
1023
-     * Define a one-to-many relationship.
1024
-     *
1025
-     * @param  mixed       $entity
1026
-     * @param  string      $related
1027
-     * @param  string|null $foreignKey
1028
-     * @param  string|null $localKey
1029
-     * @throws MappingException
1030
-     * @return \Analogue\ORM\Relationships\HasMany
1031
-     */
1032
-    public function hasMany($entity, $related, $foreignKey = null, $localKey = null)
1033
-    {
1034
-        $foreignKey = $foreignKey ?: $this->getForeignKey();
1035
-
1036
-        $relatedMapper = Manager::getInstance()->mapper($related);
1037
-
1038
-        $table = $relatedMapper->getEntityMap()->getTable() . '.' . $foreignKey;
1039
-
1040
-        $localKey = $localKey ?: $this->getKeyName();
1041
-
1042
-        // Add the relation to the definition in map
1043
-        list(, $caller) = debug_backtrace(false);
1044
-        $relation = $caller['function'];
1045
-        $this->relatedClasses[$relation] = $related;
993
+		$mapper = Manager::getInstance()->mapper(get_class($entity));
994
+
995
+		// If the type value is null it is probably safe to assume we're eager loading
996
+		// the relationship. When that is the case we will pass in a dummy query as
997
+		// there are multiple types in the morph and we can't use single queries.
998
+		$factory = new Factory;
999
+		$wrapper = $factory->make($entity);
1000
+
1001
+		if (is_null($class = $wrapper->getEntityAttribute($type))) {
1002
+			return new MorphTo(
1003
+				$mapper, $entity, $id, null, $type, $name
1004
+			);
1005
+		}
1006
+
1007
+		// If we are not eager loading the relationship we will essentially treat this
1008
+		// as a belongs-to style relationship since morph-to extends that class and
1009
+		// we will pass in the appropriate values so that it behaves as expected.
1010
+		else {
1011
+			$class = Manager::getInstance()->getInverseMorphMap($class);
1012
+			$relatedMapper = Manager::getInstance()->mapper($class);
1013
+
1014
+			$foreignKey = $relatedMapper->getEntityMap()->getKeyName();
1015
+
1016
+			return new MorphTo(
1017
+				$relatedMapper, $entity, $id, $foreignKey, $type, $name
1018
+			);
1019
+		}
1020
+	}
1021
+
1022
+	/**
1023
+	 * Define a one-to-many relationship.
1024
+	 *
1025
+	 * @param  mixed       $entity
1026
+	 * @param  string      $related
1027
+	 * @param  string|null $foreignKey
1028
+	 * @param  string|null $localKey
1029
+	 * @throws MappingException
1030
+	 * @return \Analogue\ORM\Relationships\HasMany
1031
+	 */
1032
+	public function hasMany($entity, $related, $foreignKey = null, $localKey = null)
1033
+	{
1034
+		$foreignKey = $foreignKey ?: $this->getForeignKey();
1035
+
1036
+		$relatedMapper = Manager::getInstance()->mapper($related);
1037
+
1038
+		$table = $relatedMapper->getEntityMap()->getTable() . '.' . $foreignKey;
1039
+
1040
+		$localKey = $localKey ?: $this->getKeyName();
1041
+
1042
+		// Add the relation to the definition in map
1043
+		list(, $caller) = debug_backtrace(false);
1044
+		$relation = $caller['function'];
1045
+		$this->relatedClasses[$relation] = $related;
1046 1046
         
1047
-        $this->addManyRelation($relation);
1048
-        $this->addForeignRelation($relation);
1047
+		$this->addManyRelation($relation);
1048
+		$this->addForeignRelation($relation);
1049 1049
 
1050
-        return new HasMany($relatedMapper, $entity, $table, $localKey);
1051
-    }
1050
+		return new HasMany($relatedMapper, $entity, $table, $localKey);
1051
+	}
1052 1052
 
1053
-    /**
1054
-     * Define a has-many-through relationship.
1055
-     *
1056
-     * @param  mixed       $entity
1057
-     * @param  string      $related
1058
-     * @param  string      $through
1059
-     * @param  string|null $firstKey
1060
-     * @param  string|null $secondKey
1061
-     * @throws MappingException
1062
-     * @return \Analogue\ORM\Relationships\HasManyThrough
1063
-     */
1064
-    public function hasManyThrough($entity, $related, $through, $firstKey = null, $secondKey = null)
1065
-    {
1066
-        $relatedMapper = Manager::getInstance()->mapper($related);
1053
+	/**
1054
+	 * Define a has-many-through relationship.
1055
+	 *
1056
+	 * @param  mixed       $entity
1057
+	 * @param  string      $related
1058
+	 * @param  string      $through
1059
+	 * @param  string|null $firstKey
1060
+	 * @param  string|null $secondKey
1061
+	 * @throws MappingException
1062
+	 * @return \Analogue\ORM\Relationships\HasManyThrough
1063
+	 */
1064
+	public function hasManyThrough($entity, $related, $through, $firstKey = null, $secondKey = null)
1065
+	{
1066
+		$relatedMapper = Manager::getInstance()->mapper($related);
1067 1067
 
1068
-        $throughMapper = Manager::getInstance()->mapper($through);
1068
+		$throughMapper = Manager::getInstance()->mapper($through);
1069 1069
 
1070 1070
 
1071
-        $firstKey = $firstKey ?: $this->getForeignKey();
1071
+		$firstKey = $firstKey ?: $this->getForeignKey();
1072 1072
 
1073
-        $throughMap = $throughMapper->getEntityMap();
1073
+		$throughMap = $throughMapper->getEntityMap();
1074 1074
 
1075
-        $secondKey = $secondKey ?: $throughMap->getForeignKey();
1075
+		$secondKey = $secondKey ?: $throughMap->getForeignKey();
1076 1076
 
1077
-        // Add the relation to the definition in map
1078
-        list(, $caller) = debug_backtrace(false);
1079
-        $relation = $caller['function'];
1080
-        $this->relatedClasses[$relation] = $related;
1077
+		// Add the relation to the definition in map
1078
+		list(, $caller) = debug_backtrace(false);
1079
+		$relation = $caller['function'];
1080
+		$this->relatedClasses[$relation] = $related;
1081 1081
         
1082
-        $this->addManyRelation($relation);
1083
-        $this->addForeignRelation($relation);
1084
-
1085
-        return new HasManyThrough($relatedMapper, $entity, $throughMap, $firstKey, $secondKey);
1086
-    }
1087
-
1088
-    /**
1089
-     * Define a polymorphic one-to-many relationship.
1090
-     *
1091
-     * @param  mixed       $entity
1092
-     * @param  string      $related
1093
-     * @param  string      $name
1094
-     * @param  string|null $type
1095
-     * @param  string|null $id
1096
-     * @param  string|null $localKey
1097
-     * @return \Analogue\ORM\Relationships\MorphMany
1098
-     */
1099
-    public function morphMany($entity, $related, $name, $type = null, $id = null, $localKey = null)
1100
-    {
1101
-        // Here we will gather up the morph type and ID for the relationship so that we
1102
-        // can properly query the intermediate table of a relation. Finally, we will
1103
-        // get the table and create the relationship instances for the developers.
1104
-        list($type, $id) = $this->getMorphs($name, $type, $id);
1105
-
1106
-        $relatedMapper = Manager::getInstance()->mapper($related);
1107
-
1108
-        $table = $relatedMapper->getEntityMap()->getTable();
1109
-
1110
-        $localKey = $localKey ?: $this->getKeyName();
1111
-
1112
-        // Add the relation to the definition in map
1113
-        list(, $caller) = debug_backtrace(false);
1114
-        $relation = $caller['function'];
1115
-        $this->relatedClasses[$relation] = $related;
1082
+		$this->addManyRelation($relation);
1083
+		$this->addForeignRelation($relation);
1084
+
1085
+		return new HasManyThrough($relatedMapper, $entity, $throughMap, $firstKey, $secondKey);
1086
+	}
1087
+
1088
+	/**
1089
+	 * Define a polymorphic one-to-many relationship.
1090
+	 *
1091
+	 * @param  mixed       $entity
1092
+	 * @param  string      $related
1093
+	 * @param  string      $name
1094
+	 * @param  string|null $type
1095
+	 * @param  string|null $id
1096
+	 * @param  string|null $localKey
1097
+	 * @return \Analogue\ORM\Relationships\MorphMany
1098
+	 */
1099
+	public function morphMany($entity, $related, $name, $type = null, $id = null, $localKey = null)
1100
+	{
1101
+		// Here we will gather up the morph type and ID for the relationship so that we
1102
+		// can properly query the intermediate table of a relation. Finally, we will
1103
+		// get the table and create the relationship instances for the developers.
1104
+		list($type, $id) = $this->getMorphs($name, $type, $id);
1105
+
1106
+		$relatedMapper = Manager::getInstance()->mapper($related);
1107
+
1108
+		$table = $relatedMapper->getEntityMap()->getTable();
1109
+
1110
+		$localKey = $localKey ?: $this->getKeyName();
1111
+
1112
+		// Add the relation to the definition in map
1113
+		list(, $caller) = debug_backtrace(false);
1114
+		$relation = $caller['function'];
1115
+		$this->relatedClasses[$relation] = $related;
1116 1116
         
1117
-        $this->addManyRelation($relation);
1118
-        $this->addForeignRelation($relation);
1119
-
1120
-        return new MorphMany($relatedMapper, $entity, $table . '.' . $type, $table . '.' . $id, $localKey);
1121
-    }
1122
-
1123
-    /**
1124
-     * Define a many-to-many relationship.
1125
-     *
1126
-     * @param  mixed       $entity
1127
-     * @param  string      $relatedClass
1128
-     * @param  string|null $table
1129
-     * @param  string|null $foreignKey
1130
-     * @param  string|null $otherKey
1131
-     * @param  string|null $relation
1132
-     * @throws MappingException
1133
-     * @return \Analogue\ORM\Relationships\BelongsToMany
1134
-     */
1135
-    public function belongsToMany($entity, $related, $table = null, $foreignKey = null, $otherKey = null)
1136
-    {
1137
-        // Add the relation to the definition in map
1138
-        list(, $caller) = debug_backtrace(false);
1139
-        $relation = $caller['function'];
1140
-        $this->relatedClasses[$relation] = $related;
1141
-
1142
-        $this->addManyRelation($relation);
1143
-        $this->addForeignRelation($relation);
1144
-        $this->addPivotRelation($relation);
1145
-
1146
-        // First, we'll need to determine the foreign key and "other key" for the
1147
-        // relationship. Once we have determined the keys we'll make the query
1148
-        // instances as well as the relationship instances we need for this.
1149
-        $foreignKey = $foreignKey ?: $this->getForeignKey();
1150
-
1151
-        $relatedMapper = Manager::getInstance()->mapper($related);
1152
-
1153
-        $relatedMap = $relatedMapper->getEntityMap();
1154
-
1155
-        $otherKey = $otherKey ?: $relatedMap->getForeignKey();
1156
-
1157
-        // If no table name was provided, we can guess it by concatenating the two
1158
-        // models using underscores in alphabetical order. The two model names
1159
-        // are transformed to snake case from their default CamelCase also.
1160
-        if (is_null($table)) {
1161
-            $table = $this->joiningTable($relatedMap);
1162
-        }
1163
-
1164
-        return new BelongsToMany($relatedMapper, $entity, $table, $foreignKey, $otherKey, $relation);
1165
-    }
1166
-
1167
-    /**
1168
-     * Define a polymorphic many-to-many relationship.
1169
-     *
1170
-     * @param  mixed       $entity
1171
-     * @param  string      $related
1172
-     * @param  string      $name
1173
-     * @param  string|null $table
1174
-     * @param  string|null $foreignKey
1175
-     * @param  string|null $otherKey
1176
-     * @param  bool        $inverse
1177
-     * @throws MappingException
1178
-     * @return \Analogue\ORM\Relationships\MorphToMany
1179
-     */
1180
-    public function morphToMany($entity, $related, $name, $table = null, $foreignKey = null, $otherKey = null, $inverse = false)
1181
-    {
1182
-        // Add the relation to the definition in map
1183
-        list(, $caller) = debug_backtrace(false);
1184
-        $relation = $caller['function'];
1185
-        $this->relatedClasses[$relation] = $related;
1186
-
1187
-        $this->addManyRelation($relation);
1188
-        $this->addForeignRelation($relation);
1189
-        $this->addPivotRelation($relation);
1190
-
1191
-        // First, we will need to determine the foreign key and "other key" for the
1192
-        // relationship. Once we have determined the keys we will make the query
1193
-        // instances, as well as the relationship instances we need for these.
1194
-        $foreignKey = $foreignKey ?: $name . '_id';
1195
-
1196
-        $relatedMapper = Manager::getInstance()->mapper($related);
1197
-
1198
-        $otherKey = $otherKey ?: $relatedMapper->getEntityMap()->getForeignKey();
1199
-
1200
-        $table = $table ?: str_plural($name);
1201
-
1202
-        return new MorphToMany($relatedMapper, $entity, $name, $table, $foreignKey, $otherKey, $caller, $inverse);
1203
-    }
1204
-
1205
-    /**
1206
-     * Define a polymorphic, inverse many-to-many relationship.
1207
-     *
1208
-     * @param  mixed       $entity
1209
-     * @param  string      $related
1210
-     * @param  string      $name
1211
-     * @param  string|null $table
1212
-     * @param  string|null $foreignKey
1213
-     * @param  string|null $otherKey
1214
-     * @throws MappingException
1215
-     * @return \Analogue\ORM\Relationships\MorphToMany
1216
-     */
1217
-    public function morphedByMany($entity, $related, $name, $table = null, $foreignKey = null, $otherKey = null)
1218
-    {
1219
-        // Add the relation to the definition in map
1220
-        list(, $caller) = debug_backtrace(false);
1221
-        $relation = $caller['function'];
1222
-        $this->relatedClasses[$relation] = $related;
1223
-
1224
-        $this->addManyRelation($relation);
1225
-        $this->addForeignRelation($relation);
1226
-
1227
-        $foreignKey = $foreignKey ?: $this->getForeignKey();
1228
-
1229
-        // For the inverse of the polymorphic many-to-many relations, we will change
1230
-        // the way we determine the foreign and other keys, as it is the opposite
1231
-        // of the morph-to-many method since we're figuring out these inverses.
1232
-        $otherKey = $otherKey ?: $name . '_id';
1233
-
1234
-        return $this->morphToMany($entity, $related, $name, $table, $foreignKey, $otherKey, true);
1235
-    }
1236
-
1237
-    /**
1238
-     * Get the joining table name for a many-to-many relation.
1239
-     *
1240
-     * @param  EntityMap $relatedMap
1241
-     * @return string
1242
-     */
1243
-    public function joiningTable($relatedMap)
1244
-    {
1245
-        // The joining table name, by convention, is simply the snake cased models
1246
-        // sorted alphabetically and concatenated with an underscore, so we can
1247
-        // just sort the models and join them together to get the table name.
1248
-        $base = $this->getTable();
1249
-
1250
-        $related = $relatedMap->getTable();
1251
-
1252
-        $tables = [$related, $base];
1253
-
1254
-        // Now that we have the model names in an array we can just sort them and
1255
-        // use the implode function to join them together with an underscores,
1256
-        // which is typically used by convention within the database system.
1257
-        sort($tables);
1258
-
1259
-        return strtolower(implode('_', $tables));
1260
-    }
1261
-
1262
-    /**
1263
-     * Get the polymorphic relationship columns.
1264
-     *
1265
-     * @param  string $name
1266
-     * @param  string $type
1267
-     * @param  string $id
1268
-     * @return string[]
1269
-     */
1270
-    protected function getMorphs($name, $type, $id)
1271
-    {
1272
-        $type = $type ?: $name . '_type';
1273
-
1274
-        $id = $id ?: $name . '_id';
1275
-
1276
-        return [$type, $id];
1277
-    }
1278
-
1279
-    /**
1280
-     * Get the class name for polymorphic relations.
1281
-     *
1282
-     * @return string
1283
-     */
1284
-    public function getMorphClass()
1285
-    {
1286
-        $morphClass = Manager::getInstance()->getMorphMap($this->getClass());
1287
-        return $this->morphClass ?: $morphClass;
1288
-    }
1289
-
1290
-    /**
1291
-     * Create a new Entity Collection instance.
1292
-     *
1293
-     * @param  array $entities
1294
-     * @return \Analogue\ORM\EntityCollection
1295
-     */
1296
-    public function newCollection(array $entities = [])
1297
-    {
1298
-        $collection = new EntityCollection($entities, $this);
1299
-        return $collection->keyBy($this->getKeyName());
1300
-    }
1301
-
1302
-    /**
1303
-     * Process EntityMap parsing at initialization time
1304
-     *
1305
-     * @return void
1306
-     */
1307
-    public function initialize()
1308
-    {
1309
-        $userMethods = $this->getCustomMethods();
1310
-
1311
-        // Parse EntityMap for method based relationship
1312
-        if (count($userMethods) > 0) {
1313
-            $this->relationships = $this->parseMethodsForRelationship($userMethods);
1314
-        }
1315
-
1316
-        // Parse EntityMap for dynamic relationships
1317
-        if (count($this->dynamicRelationships) > 0) {
1318
-            $this->relationships = $this->relationships + $this->getDynamicRelationships();
1319
-        }
1320
-    }
1321
-
1322
-    /**
1323
-     * Parse every relationships on the EntityMap and sort
1324
-     * them by type.
1325
-     *
1326
-     * @return void
1327
-     */
1328
-    public function boot()
1329
-    {
1330
-        if (count($this->relationships > 0)) {
1331
-            $this->sortRelationshipsByType();
1332
-        }
1333
-    }
1334
-
1335
-    /**
1336
-     * Get Methods that has been added in the child class.
1337
-     *
1338
-     * @return array
1339
-     */
1340
-    protected function getCustomMethods()
1341
-    {
1342
-        $mapMethods = get_class_methods($this);
1343
-
1344
-        $parentsMethods = get_class_methods('Analogue\ORM\EntityMap');
1345
-
1346
-        return array_diff($mapMethods, $parentsMethods);
1347
-    }
1348
-
1349
-    /**
1350
-     * Parse user's class methods for relationships
1351
-     *
1352
-     * @param  array $customMethods
1353
-     * @return array
1354
-     */
1355
-    protected function parseMethodsForRelationship(array $customMethods)
1356
-    {
1357
-        $relationships = [];
1358
-
1359
-        $class = new ReflectionClass(get_class($this));
1360
-
1361
-        // Get the mapped Entity class, as we will detect relationships
1362
-        // methods by testing that the first argument is type-hinted to
1363
-        // the same class as the mapped Entity.
1364
-        $entityClass = $this->getClass();
1365
-
1366
-        foreach ($customMethods as $methodName) {
1367
-            $method = $class->getMethod($methodName);
1368
-
1369
-            if ($method->getNumberOfParameters() > 0) {
1370
-                $params = $method->getParameters();
1371
-
1372
-                if ($params[0]->getClass() && ($params[0]->getClass()->name == $entityClass || is_subclass_of($entityClass, $params[0]->getClass()->name))) {
1373
-                    $relationships[] = $methodName;
1374
-                }
1375
-            }
1376
-        }
1377
-
1378
-        return $relationships;
1379
-    }
1380
-
1381
-    /**
1382
-     * Sort Relationships methods by type
1383
-     * 
1384
-     * TODO : replace this by direclty setting these value
1385
-     * in the corresponding methods, so we won't need
1386
-     * the correpondancy tabble
1387
-     * 
1388
-     * @return void
1389
-     */
1390
-    protected function sortRelationshipsByType()
1391
-    {
1392
-        $entityClass = $this->getClass();
1393
-
1394
-        // Instantiate a dummy entity which we will pass to relationship methods.
1395
-        $entity = unserialize(sprintf('O:%d:"%s":0:{}', strlen($entityClass), $entityClass));
1396
-
1397
-        foreach ($this->relationships as $relation) {
1398
-            $this->$relation($entity);
1399
-        }
1400
-    }
1401
-
1402
-    /**
1403
-     * Override this method for custom entity instantiation
1404
-     *
1405
-     * @return null
1406
-     */
1407
-    public function activator()
1408
-    {
1409
-        return null;
1410
-    }
1411
-
1412
-    /**
1413
-     * Magic call to dynamic relationships
1414
-     *
1415
-     * @param  string $method
1416
-     * @param  array  $parameters
1417
-     * @throws Exception
1418
-     * @return mixed
1419
-     */
1420
-    public function __call($method, $parameters)
1421
-    {
1422
-        if (!array_key_exists($method, $this->dynamicRelationships)) {
1423
-            throw new Exception(get_class($this) . " has no method $method");
1424
-        }
1425
-
1426
-        // Add $this to parameters so the closure can call relationship method on the map.
1427
-        $parameters[] = $this;
1428
-
1429
-        return  call_user_func_array([$this->dynamicRelationships[$method], $parameters]);
1430
-    }
1117
+		$this->addManyRelation($relation);
1118
+		$this->addForeignRelation($relation);
1119
+
1120
+		return new MorphMany($relatedMapper, $entity, $table . '.' . $type, $table . '.' . $id, $localKey);
1121
+	}
1122
+
1123
+	/**
1124
+	 * Define a many-to-many relationship.
1125
+	 *
1126
+	 * @param  mixed       $entity
1127
+	 * @param  string      $relatedClass
1128
+	 * @param  string|null $table
1129
+	 * @param  string|null $foreignKey
1130
+	 * @param  string|null $otherKey
1131
+	 * @param  string|null $relation
1132
+	 * @throws MappingException
1133
+	 * @return \Analogue\ORM\Relationships\BelongsToMany
1134
+	 */
1135
+	public function belongsToMany($entity, $related, $table = null, $foreignKey = null, $otherKey = null)
1136
+	{
1137
+		// Add the relation to the definition in map
1138
+		list(, $caller) = debug_backtrace(false);
1139
+		$relation = $caller['function'];
1140
+		$this->relatedClasses[$relation] = $related;
1141
+
1142
+		$this->addManyRelation($relation);
1143
+		$this->addForeignRelation($relation);
1144
+		$this->addPivotRelation($relation);
1145
+
1146
+		// First, we'll need to determine the foreign key and "other key" for the
1147
+		// relationship. Once we have determined the keys we'll make the query
1148
+		// instances as well as the relationship instances we need for this.
1149
+		$foreignKey = $foreignKey ?: $this->getForeignKey();
1150
+
1151
+		$relatedMapper = Manager::getInstance()->mapper($related);
1152
+
1153
+		$relatedMap = $relatedMapper->getEntityMap();
1154
+
1155
+		$otherKey = $otherKey ?: $relatedMap->getForeignKey();
1156
+
1157
+		// If no table name was provided, we can guess it by concatenating the two
1158
+		// models using underscores in alphabetical order. The two model names
1159
+		// are transformed to snake case from their default CamelCase also.
1160
+		if (is_null($table)) {
1161
+			$table = $this->joiningTable($relatedMap);
1162
+		}
1163
+
1164
+		return new BelongsToMany($relatedMapper, $entity, $table, $foreignKey, $otherKey, $relation);
1165
+	}
1166
+
1167
+	/**
1168
+	 * Define a polymorphic many-to-many relationship.
1169
+	 *
1170
+	 * @param  mixed       $entity
1171
+	 * @param  string      $related
1172
+	 * @param  string      $name
1173
+	 * @param  string|null $table
1174
+	 * @param  string|null $foreignKey
1175
+	 * @param  string|null $otherKey
1176
+	 * @param  bool        $inverse
1177
+	 * @throws MappingException
1178
+	 * @return \Analogue\ORM\Relationships\MorphToMany
1179
+	 */
1180
+	public function morphToMany($entity, $related, $name, $table = null, $foreignKey = null, $otherKey = null, $inverse = false)
1181
+	{
1182
+		// Add the relation to the definition in map
1183
+		list(, $caller) = debug_backtrace(false);
1184
+		$relation = $caller['function'];
1185
+		$this->relatedClasses[$relation] = $related;
1186
+
1187
+		$this->addManyRelation($relation);
1188
+		$this->addForeignRelation($relation);
1189
+		$this->addPivotRelation($relation);
1190
+
1191
+		// First, we will need to determine the foreign key and "other key" for the
1192
+		// relationship. Once we have determined the keys we will make the query
1193
+		// instances, as well as the relationship instances we need for these.
1194
+		$foreignKey = $foreignKey ?: $name . '_id';
1195
+
1196
+		$relatedMapper = Manager::getInstance()->mapper($related);
1197
+
1198
+		$otherKey = $otherKey ?: $relatedMapper->getEntityMap()->getForeignKey();
1199
+
1200
+		$table = $table ?: str_plural($name);
1201
+
1202
+		return new MorphToMany($relatedMapper, $entity, $name, $table, $foreignKey, $otherKey, $caller, $inverse);
1203
+	}
1204
+
1205
+	/**
1206
+	 * Define a polymorphic, inverse many-to-many relationship.
1207
+	 *
1208
+	 * @param  mixed       $entity
1209
+	 * @param  string      $related
1210
+	 * @param  string      $name
1211
+	 * @param  string|null $table
1212
+	 * @param  string|null $foreignKey
1213
+	 * @param  string|null $otherKey
1214
+	 * @throws MappingException
1215
+	 * @return \Analogue\ORM\Relationships\MorphToMany
1216
+	 */
1217
+	public function morphedByMany($entity, $related, $name, $table = null, $foreignKey = null, $otherKey = null)
1218
+	{
1219
+		// Add the relation to the definition in map
1220
+		list(, $caller) = debug_backtrace(false);
1221
+		$relation = $caller['function'];
1222
+		$this->relatedClasses[$relation] = $related;
1223
+
1224
+		$this->addManyRelation($relation);
1225
+		$this->addForeignRelation($relation);
1226
+
1227
+		$foreignKey = $foreignKey ?: $this->getForeignKey();
1228
+
1229
+		// For the inverse of the polymorphic many-to-many relations, we will change
1230
+		// the way we determine the foreign and other keys, as it is the opposite
1231
+		// of the morph-to-many method since we're figuring out these inverses.
1232
+		$otherKey = $otherKey ?: $name . '_id';
1233
+
1234
+		return $this->morphToMany($entity, $related, $name, $table, $foreignKey, $otherKey, true);
1235
+	}
1236
+
1237
+	/**
1238
+	 * Get the joining table name for a many-to-many relation.
1239
+	 *
1240
+	 * @param  EntityMap $relatedMap
1241
+	 * @return string
1242
+	 */
1243
+	public function joiningTable($relatedMap)
1244
+	{
1245
+		// The joining table name, by convention, is simply the snake cased models
1246
+		// sorted alphabetically and concatenated with an underscore, so we can
1247
+		// just sort the models and join them together to get the table name.
1248
+		$base = $this->getTable();
1249
+
1250
+		$related = $relatedMap->getTable();
1251
+
1252
+		$tables = [$related, $base];
1253
+
1254
+		// Now that we have the model names in an array we can just sort them and
1255
+		// use the implode function to join them together with an underscores,
1256
+		// which is typically used by convention within the database system.
1257
+		sort($tables);
1258
+
1259
+		return strtolower(implode('_', $tables));
1260
+	}
1261
+
1262
+	/**
1263
+	 * Get the polymorphic relationship columns.
1264
+	 *
1265
+	 * @param  string $name
1266
+	 * @param  string $type
1267
+	 * @param  string $id
1268
+	 * @return string[]
1269
+	 */
1270
+	protected function getMorphs($name, $type, $id)
1271
+	{
1272
+		$type = $type ?: $name . '_type';
1273
+
1274
+		$id = $id ?: $name . '_id';
1275
+
1276
+		return [$type, $id];
1277
+	}
1278
+
1279
+	/**
1280
+	 * Get the class name for polymorphic relations.
1281
+	 *
1282
+	 * @return string
1283
+	 */
1284
+	public function getMorphClass()
1285
+	{
1286
+		$morphClass = Manager::getInstance()->getMorphMap($this->getClass());
1287
+		return $this->morphClass ?: $morphClass;
1288
+	}
1289
+
1290
+	/**
1291
+	 * Create a new Entity Collection instance.
1292
+	 *
1293
+	 * @param  array $entities
1294
+	 * @return \Analogue\ORM\EntityCollection
1295
+	 */
1296
+	public function newCollection(array $entities = [])
1297
+	{
1298
+		$collection = new EntityCollection($entities, $this);
1299
+		return $collection->keyBy($this->getKeyName());
1300
+	}
1301
+
1302
+	/**
1303
+	 * Process EntityMap parsing at initialization time
1304
+	 *
1305
+	 * @return void
1306
+	 */
1307
+	public function initialize()
1308
+	{
1309
+		$userMethods = $this->getCustomMethods();
1310
+
1311
+		// Parse EntityMap for method based relationship
1312
+		if (count($userMethods) > 0) {
1313
+			$this->relationships = $this->parseMethodsForRelationship($userMethods);
1314
+		}
1315
+
1316
+		// Parse EntityMap for dynamic relationships
1317
+		if (count($this->dynamicRelationships) > 0) {
1318
+			$this->relationships = $this->relationships + $this->getDynamicRelationships();
1319
+		}
1320
+	}
1321
+
1322
+	/**
1323
+	 * Parse every relationships on the EntityMap and sort
1324
+	 * them by type.
1325
+	 *
1326
+	 * @return void
1327
+	 */
1328
+	public function boot()
1329
+	{
1330
+		if (count($this->relationships > 0)) {
1331
+			$this->sortRelationshipsByType();
1332
+		}
1333
+	}
1334
+
1335
+	/**
1336
+	 * Get Methods that has been added in the child class.
1337
+	 *
1338
+	 * @return array
1339
+	 */
1340
+	protected function getCustomMethods()
1341
+	{
1342
+		$mapMethods = get_class_methods($this);
1343
+
1344
+		$parentsMethods = get_class_methods('Analogue\ORM\EntityMap');
1345
+
1346
+		return array_diff($mapMethods, $parentsMethods);
1347
+	}
1348
+
1349
+	/**
1350
+	 * Parse user's class methods for relationships
1351
+	 *
1352
+	 * @param  array $customMethods
1353
+	 * @return array
1354
+	 */
1355
+	protected function parseMethodsForRelationship(array $customMethods)
1356
+	{
1357
+		$relationships = [];
1358
+
1359
+		$class = new ReflectionClass(get_class($this));
1360
+
1361
+		// Get the mapped Entity class, as we will detect relationships
1362
+		// methods by testing that the first argument is type-hinted to
1363
+		// the same class as the mapped Entity.
1364
+		$entityClass = $this->getClass();
1365
+
1366
+		foreach ($customMethods as $methodName) {
1367
+			$method = $class->getMethod($methodName);
1368
+
1369
+			if ($method->getNumberOfParameters() > 0) {
1370
+				$params = $method->getParameters();
1371
+
1372
+				if ($params[0]->getClass() && ($params[0]->getClass()->name == $entityClass || is_subclass_of($entityClass, $params[0]->getClass()->name))) {
1373
+					$relationships[] = $methodName;
1374
+				}
1375
+			}
1376
+		}
1377
+
1378
+		return $relationships;
1379
+	}
1380
+
1381
+	/**
1382
+	 * Sort Relationships methods by type
1383
+	 * 
1384
+	 * TODO : replace this by direclty setting these value
1385
+	 * in the corresponding methods, so we won't need
1386
+	 * the correpondancy tabble
1387
+	 * 
1388
+	 * @return void
1389
+	 */
1390
+	protected function sortRelationshipsByType()
1391
+	{
1392
+		$entityClass = $this->getClass();
1393
+
1394
+		// Instantiate a dummy entity which we will pass to relationship methods.
1395
+		$entity = unserialize(sprintf('O:%d:"%s":0:{}', strlen($entityClass), $entityClass));
1396
+
1397
+		foreach ($this->relationships as $relation) {
1398
+			$this->$relation($entity);
1399
+		}
1400
+	}
1401
+
1402
+	/**
1403
+	 * Override this method for custom entity instantiation
1404
+	 *
1405
+	 * @return null
1406
+	 */
1407
+	public function activator()
1408
+	{
1409
+		return null;
1410
+	}
1411
+
1412
+	/**
1413
+	 * Magic call to dynamic relationships
1414
+	 *
1415
+	 * @param  string $method
1416
+	 * @param  array  $parameters
1417
+	 * @throws Exception
1418
+	 * @return mixed
1419
+	 */
1420
+	public function __call($method, $parameters)
1421
+	{
1422
+		if (!array_key_exists($method, $this->dynamicRelationships)) {
1423
+			throw new Exception(get_class($this) . " has no method $method");
1424
+		}
1425
+
1426
+		// Add $this to parameters so the closure can call relationship method on the map.
1427
+		$parameters[] = $this;
1428
+
1429
+		return  call_user_func_array([$this->dynamicRelationships[$method], $parameters]);
1430
+	}
1431 1431
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -418,7 +418,7 @@  discard block
 block discarded – undo
418 418
         if (!is_null($this->sequence)) {
419 419
             return $this->sequence;
420 420
         } else {
421
-            return $this->getTable() . '_id_seq';
421
+            return $this->getTable().'_id_seq';
422 422
         }
423 423
     }
424 424
 
@@ -640,7 +640,7 @@  discard block
 block discarded – undo
640 640
      */
641 641
     public function getQualifiedKeyName() : string
642 642
     {
643
-        return $this->getTable() . '.' . $this->getKeyName();
643
+        return $this->getTable().'.'.$this->getKeyName();
644 644
     }
645 645
 
646 646
     /**
@@ -721,7 +721,7 @@  discard block
 block discarded – undo
721 721
      */
722 722
     public function getForeignKey() : string
723 723
     {
724
-        return snake_case(class_basename($this->getClass())) . '_id';
724
+        return snake_case(class_basename($this->getClass())).'_id';
725 725
     }
726 726
 
727 727
     /**
@@ -774,7 +774,7 @@  discard block
 block discarded – undo
774 774
      */
775 775
     protected function addSingleRelation($relation)
776 776
     {
777
-        if(! in_array($relation, $this->singleRelations)) {
777
+        if (!in_array($relation, $this->singleRelations)) {
778 778
             $this->singleRelations[] = $relation;
779 779
         }
780 780
     }
@@ -786,7 +786,7 @@  discard block
 block discarded – undo
786 786
      */
787 787
     protected function addForeignRelation($relation)
788 788
     {
789
-        if(! in_array($relation, $this->foreignRelations)) {
789
+        if (!in_array($relation, $this->foreignRelations)) {
790 790
             $this->foreignRelations[] = $relation;
791 791
         }
792 792
     }
@@ -798,7 +798,7 @@  discard block
 block discarded – undo
798 798
      */
799 799
     protected function addNonProxyRelation($relation)
800 800
     {
801
-        if(! in_array($relation, $this->nonProxyRelationships)) {
801
+        if (!in_array($relation, $this->nonProxyRelationships)) {
802 802
             $this->nonProxyRelationships[] = $relation;
803 803
         }
804 804
     }
@@ -810,7 +810,7 @@  discard block
 block discarded – undo
810 810
      */
811 811
     protected function addLocalRelation($relation)
812 812
     {
813
-        if(! in_array($relation, $this->localRelations)) {
813
+        if (!in_array($relation, $this->localRelations)) {
814 814
             $this->localRelations[] = $relation;
815 815
         }
816 816
     }
@@ -822,7 +822,7 @@  discard block
 block discarded – undo
822 822
      */
823 823
     protected function addManyRelation($relation)
824 824
     {
825
-        if(! in_array($relation, $this->manyRelations)) {
825
+        if (!in_array($relation, $this->manyRelations)) {
826 826
             $this->manyRelations[] = $relation;
827 827
         }
828 828
     }
@@ -834,7 +834,7 @@  discard block
 block discarded – undo
834 834
      */
835 835
     protected function addPivotRelation($relation)
836 836
     {
837
-        if(! in_array($relation, $this->pivotRelations)) {
837
+        if (!in_array($relation, $this->pivotRelations)) {
838 838
             $this->pivotRelations[] = $relation;
839 839
         }
840 840
     }
@@ -870,11 +870,11 @@  discard block
 block discarded – undo
870 870
 
871 871
         // This relationship will always be eager loaded, as proxying it would
872 872
         // mean having an object that doesn't actually exists.
873
-        if(! in_array($relation, $this->with)) {
873
+        if (!in_array($relation, $this->with)) {
874 874
             $this->with[] = $relation;
875 875
         }
876 876
 
877
-        return new HasOne($relatedMapper, $entity, $relatedMap->getTable() . '.' . $foreignKey, $localKey);
877
+        return new HasOne($relatedMapper, $entity, $relatedMap->getTable().'.'.$foreignKey, $localKey);
878 878
     }
879 879
 
880 880
     /**
@@ -910,11 +910,11 @@  discard block
 block discarded – undo
910 910
 
911 911
         // This relationship will always be eager loaded, as proxying it would
912 912
         // mean having an object that doesn't actually exists.
913
-        if(! in_array($relation, $this->with)) {
913
+        if (!in_array($relation, $this->with)) {
914 914
             $this->with[] = $relation;
915 915
         }
916 916
         
917
-        return new MorphOne($relatedMapper, $entity, $table . '.' . $type, $table . '.' . $id, $localKey);
917
+        return new MorphOne($relatedMapper, $entity, $table.'.'.$type, $table.'.'.$id, $localKey);
918 918
     }
919 919
 
920 920
     /**
@@ -942,7 +942,7 @@  discard block
 block discarded – undo
942 942
         // foreign key name by using the name of the relationship function, which
943 943
         // when combined with an "_id" should conventionally match the columns.
944 944
         if (is_null($foreignKey)) {
945
-            $foreignKey = snake_case($relation) . '_id';
945
+            $foreignKey = snake_case($relation).'_id';
946 946
         }
947 947
 
948 948
         $this->localForeignKeys[$relation] = $foreignKey;
@@ -1035,7 +1035,7 @@  discard block
 block discarded – undo
1035 1035
 
1036 1036
         $relatedMapper = Manager::getInstance()->mapper($related);
1037 1037
 
1038
-        $table = $relatedMapper->getEntityMap()->getTable() . '.' . $foreignKey;
1038
+        $table = $relatedMapper->getEntityMap()->getTable().'.'.$foreignKey;
1039 1039
 
1040 1040
         $localKey = $localKey ?: $this->getKeyName();
1041 1041
 
@@ -1117,7 +1117,7 @@  discard block
 block discarded – undo
1117 1117
         $this->addManyRelation($relation);
1118 1118
         $this->addForeignRelation($relation);
1119 1119
 
1120
-        return new MorphMany($relatedMapper, $entity, $table . '.' . $type, $table . '.' . $id, $localKey);
1120
+        return new MorphMany($relatedMapper, $entity, $table.'.'.$type, $table.'.'.$id, $localKey);
1121 1121
     }
1122 1122
 
1123 1123
     /**
@@ -1191,7 +1191,7 @@  discard block
 block discarded – undo
1191 1191
         // First, we will need to determine the foreign key and "other key" for the
1192 1192
         // relationship. Once we have determined the keys we will make the query
1193 1193
         // instances, as well as the relationship instances we need for these.
1194
-        $foreignKey = $foreignKey ?: $name . '_id';
1194
+        $foreignKey = $foreignKey ?: $name.'_id';
1195 1195
 
1196 1196
         $relatedMapper = Manager::getInstance()->mapper($related);
1197 1197
 
@@ -1229,7 +1229,7 @@  discard block
 block discarded – undo
1229 1229
         // For the inverse of the polymorphic many-to-many relations, we will change
1230 1230
         // the way we determine the foreign and other keys, as it is the opposite
1231 1231
         // of the morph-to-many method since we're figuring out these inverses.
1232
-        $otherKey = $otherKey ?: $name . '_id';
1232
+        $otherKey = $otherKey ?: $name.'_id';
1233 1233
 
1234 1234
         return $this->morphToMany($entity, $related, $name, $table, $foreignKey, $otherKey, true);
1235 1235
     }
@@ -1269,9 +1269,9 @@  discard block
 block discarded – undo
1269 1269
      */
1270 1270
     protected function getMorphs($name, $type, $id)
1271 1271
     {
1272
-        $type = $type ?: $name . '_type';
1272
+        $type = $type ?: $name.'_type';
1273 1273
 
1274
-        $id = $id ?: $name . '_id';
1274
+        $id = $id ?: $name.'_id';
1275 1275
 
1276 1276
         return [$type, $id];
1277 1277
     }
@@ -1420,7 +1420,7 @@  discard block
 block discarded – undo
1420 1420
     public function __call($method, $parameters)
1421 1421
     {
1422 1422
         if (!array_key_exists($method, $this->dynamicRelationships)) {
1423
-            throw new Exception(get_class($this) . " has no method $method");
1423
+            throw new Exception(get_class($this)." has no method $method");
1424 1424
         }
1425 1425
 
1426 1426
         // Add $this to parameters so the closure can call relationship method on the map.
Please login to merge, or discard this patch.
src/System/EntityBuilder.php 1 patch
Indentation   +153 added lines, -153 removed lines patch added patch discarded remove patch
@@ -9,159 +9,159 @@
 block discarded – undo
9 9
  */
10 10
 class EntityBuilder
11 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();
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 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
-    }
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 166
 
167 167
 }
168 168
\ No newline at end of file
Please login to merge, or discard this patch.