Completed
Branch master (a17b64)
by Rémi
15:50
created
src/System/Aggregate.php 2 patches
Indentation   +1042 added lines, -1042 removed lines patch added patch discarded remove patch
@@ -16,1068 +16,1068 @@
 block discarded – undo
16 16
  */
17 17
 class Aggregate implements InternallyMappable
18 18
 {
19
-    /**
20
-     * The Root Entity
21
-     *
22
-     * @var \Analogue\ORM\System\Wrappers\Wrapper
23
-     */
24
-    protected $wrappedEntity;
25
-
26
-    /** 
27
-     * Class of the entity being aggregated
28
-     * 
29
-     * @var string
30
-     */
31
-    protected $class;
32
-
33
-    /**
34
-     * Parent Root Aggregate
35
-     *
36
-     * @var \Analogue\ORM\System\Aggregate
37
-     */
38
-    protected $parent;
39
-
40
-    /**
41
-     * Parent's relationship method
42
-     *
43
-     * @var string
44
-     */
45
-    protected $parentRelationship;
46
-
47
-    /**
48
-     * Root Entity
49
-     *
50
-     * @var \Analogue\ORM\System\Aggregate
51
-     */
52
-    protected $root;
53
-
54
-    /**
55
-     * An associative array containing entity's
56
-     * relationships converted to Aggregates
57
-     *
58
-     * @var array
59
-     */
60
-    protected $relationships = [];
61
-
62
-    /**
63
-     * Relationship that need post-command synchronization
64
-     *
65
-     * @var array
66
-     */
67
-    protected $needSync = [];
68
-
69
-    /**
70
-     * Mapper
71
-     *
72
-     * @var \Analogue\ORM\System\Mapper;
73
-     */
74
-    protected $mapper;
75
-
76
-    /**
77
-     * Entity Map
78
-     *
79
-     * @var \Analogue\ORM\EntityMap;
80
-     */
81
-    protected $entityMap;
82
-
83
-    /**
84
-     * Create a new Aggregated Entity instance
85
-     *
86
-     * @param mixed          $entity
87
-     * @param Aggregate|null $parent
88
-     * @param string         $parentRelationship
89
-     * @param Aggregate|null $root
90
-     * @throws MappingException
91
-     */
92
-    public function __construct($entity, Aggregate $parent = null, $parentRelationship = null, Aggregate $root = null)
93
-    {
94
-        $factory = new Factory;
19
+	/**
20
+	 * The Root Entity
21
+	 *
22
+	 * @var \Analogue\ORM\System\Wrappers\Wrapper
23
+	 */
24
+	protected $wrappedEntity;
25
+
26
+	/** 
27
+	 * Class of the entity being aggregated
28
+	 * 
29
+	 * @var string
30
+	 */
31
+	protected $class;
32
+
33
+	/**
34
+	 * Parent Root Aggregate
35
+	 *
36
+	 * @var \Analogue\ORM\System\Aggregate
37
+	 */
38
+	protected $parent;
39
+
40
+	/**
41
+	 * Parent's relationship method
42
+	 *
43
+	 * @var string
44
+	 */
45
+	protected $parentRelationship;
46
+
47
+	/**
48
+	 * Root Entity
49
+	 *
50
+	 * @var \Analogue\ORM\System\Aggregate
51
+	 */
52
+	protected $root;
53
+
54
+	/**
55
+	 * An associative array containing entity's
56
+	 * relationships converted to Aggregates
57
+	 *
58
+	 * @var array
59
+	 */
60
+	protected $relationships = [];
61
+
62
+	/**
63
+	 * Relationship that need post-command synchronization
64
+	 *
65
+	 * @var array
66
+	 */
67
+	protected $needSync = [];
68
+
69
+	/**
70
+	 * Mapper
71
+	 *
72
+	 * @var \Analogue\ORM\System\Mapper;
73
+	 */
74
+	protected $mapper;
75
+
76
+	/**
77
+	 * Entity Map
78
+	 *
79
+	 * @var \Analogue\ORM\EntityMap;
80
+	 */
81
+	protected $entityMap;
82
+
83
+	/**
84
+	 * Create a new Aggregated Entity instance
85
+	 *
86
+	 * @param mixed          $entity
87
+	 * @param Aggregate|null $parent
88
+	 * @param string         $parentRelationship
89
+	 * @param Aggregate|null $root
90
+	 * @throws MappingException
91
+	 */
92
+	public function __construct($entity, Aggregate $parent = null, $parentRelationship = null, Aggregate $root = null)
93
+	{
94
+		$factory = new Factory;
95 95
         
96
-        $this->class = get_class($entity);
96
+		$this->class = get_class($entity);
97 97
 
98
-        $this->wrappedEntity = $factory->make($entity);
98
+		$this->wrappedEntity = $factory->make($entity);
99 99
 
100
-        $this->parent = $parent;
100
+		$this->parent = $parent;
101 101
 
102
-        $this->parentRelationship = $parentRelationship;
102
+		$this->parentRelationship = $parentRelationship;
103 103
 
104
-        $this->root = $root;
104
+		$this->root = $root;
105 105
 
106
-        $mapper = $this->getMapper($entity);
106
+		$mapper = $this->getMapper($entity);
107 107
 
108
-        $this->entityMap = $mapper->getEntityMap();
108
+		$this->entityMap = $mapper->getEntityMap();
109 109
              
110
-        $this->parseRelationships();
111
-    }
112
-
113
-    /**
114
-     * Parse Every relationships defined on the entity
115
-     *
116
-     * @throws MappingException
117
-     * @return void
118
-     */
119
-    protected function parseRelationships()
120
-    {
121
-        foreach ($this->entityMap->getSingleRelationships() as $relation) {
122
-            $this->parseSingleRelationship($relation);
123
-        }
124
-
125
-        foreach ($this->entityMap->getManyRelationships() as $relation) {
126
-            $this->parseManyRelationship($relation);
127
-        }
128
-    }
129
-
130
-    /**
131
-     * Parse for values common to single & many relations
132
-     *
133
-     * @param  string $relation
134
-     * @throws MappingException
135
-     * @return mixed|boolean
136
-     */
137
-    protected function parseForCommonValues($relation)
138
-    {
139
-        if (!$this->hasAttribute($relation)) {
140
-            // If no attribute exists for this relationships
141
-            // we'll make it a simple empty array. This will
142
-            // save us from constantly checking for the attributes
143
-            // actual existence.
144
-            $this->relationships[$relation] = [];
145
-            return false;
146
-        }
147
-
148
-        $value = $this->getRelationshipValue($relation);
149
-
150
-        if (is_null($value)) {
151
-            $this->relationships[$relation] = [];
152
-
153
-            // If the relationship's content is the null value
154
-            // and the Entity's exist in DB, we'll interpret this
155
-            // as the need to detach all related Entities,
156
-            // therefore a sync operation is needed.
157
-            $this->needSync[] = $relation;
158
-            return false;
159
-        }
160
-
161
-        return $value;
162
-    }
163
-
164
-    /**
165
-     * Parse a 'single' relationship
166
-     *
167
-     * @param  string $relation
168
-     * @throws MappingException
169
-     * @return boolean
170
-     */
171
-    protected function parseSingleRelationship($relation)
172
-    {
173
-        if (!$value = $this->parseForCommonValues($relation)) {
174
-            return true;
175
-        }
110
+		$this->parseRelationships();
111
+	}
112
+
113
+	/**
114
+	 * Parse Every relationships defined on the entity
115
+	 *
116
+	 * @throws MappingException
117
+	 * @return void
118
+	 */
119
+	protected function parseRelationships()
120
+	{
121
+		foreach ($this->entityMap->getSingleRelationships() as $relation) {
122
+			$this->parseSingleRelationship($relation);
123
+		}
124
+
125
+		foreach ($this->entityMap->getManyRelationships() as $relation) {
126
+			$this->parseManyRelationship($relation);
127
+		}
128
+	}
129
+
130
+	/**
131
+	 * Parse for values common to single & many relations
132
+	 *
133
+	 * @param  string $relation
134
+	 * @throws MappingException
135
+	 * @return mixed|boolean
136
+	 */
137
+	protected function parseForCommonValues($relation)
138
+	{
139
+		if (!$this->hasAttribute($relation)) {
140
+			// If no attribute exists for this relationships
141
+			// we'll make it a simple empty array. This will
142
+			// save us from constantly checking for the attributes
143
+			// actual existence.
144
+			$this->relationships[$relation] = [];
145
+			return false;
146
+		}
147
+
148
+		$value = $this->getRelationshipValue($relation);
149
+
150
+		if (is_null($value)) {
151
+			$this->relationships[$relation] = [];
152
+
153
+			// If the relationship's content is the null value
154
+			// and the Entity's exist in DB, we'll interpret this
155
+			// as the need to detach all related Entities,
156
+			// therefore a sync operation is needed.
157
+			$this->needSync[] = $relation;
158
+			return false;
159
+		}
160
+
161
+		return $value;
162
+	}
163
+
164
+	/**
165
+	 * Parse a 'single' relationship
166
+	 *
167
+	 * @param  string $relation
168
+	 * @throws MappingException
169
+	 * @return boolean
170
+	 */
171
+	protected function parseSingleRelationship($relation)
172
+	{
173
+		if (!$value = $this->parseForCommonValues($relation)) {
174
+			return true;
175
+		}
176 176
         
177
-        if ($value instanceof Collection || is_array($value) || $value instanceof CollectionProxy) {
178
-            throw new MappingException("Entity's attribute $relation should not be array, or collection");
179
-        }
180
-
181
-        if ($value instanceof LazyLoadingInterface && !$value->isProxyInitialized()) {
182
-            $this->relationships[$relation] = [];
183
-            return true;
184
-        }
185
-
186
-        // If the attribute is a loaded proxy, swap it for its
187
-        // loaded entity.
188
-        if ($value instanceof LazyLoadingInterface && $value->isProxyInitialized()) {
189
-            $value = $value->getWrappedValueHolderValue();
190
-        }
191
-
192
-        if ($this->isParentOrRoot($value)) {
193
-            $this->relationships[$relation] = [];
194
-            return true;
195
-        }
196
-
197
-        // At this point, we can assume the attribute is an Entity instance
198
-        // so we'll treat it as such.
199
-        $subAggregate = $this->createSubAggregate($value, $relation);
177
+		if ($value instanceof Collection || is_array($value) || $value instanceof CollectionProxy) {
178
+			throw new MappingException("Entity's attribute $relation should not be array, or collection");
179
+		}
180
+
181
+		if ($value instanceof LazyLoadingInterface && !$value->isProxyInitialized()) {
182
+			$this->relationships[$relation] = [];
183
+			return true;
184
+		}
185
+
186
+		// If the attribute is a loaded proxy, swap it for its
187
+		// loaded entity.
188
+		if ($value instanceof LazyLoadingInterface && $value->isProxyInitialized()) {
189
+			$value = $value->getWrappedValueHolderValue();
190
+		}
191
+
192
+		if ($this->isParentOrRoot($value)) {
193
+			$this->relationships[$relation] = [];
194
+			return true;
195
+		}
196
+
197
+		// At this point, we can assume the attribute is an Entity instance
198
+		// so we'll treat it as such.
199
+		$subAggregate = $this->createSubAggregate($value, $relation);
200 200
          
201
-        // Even if it's a single entity, we'll store it as an array
202
-        // just for consistency with other relationships
203
-        $this->relationships[$relation] = [$subAggregate];
204
-
205
-        // We always need to check a loaded relation is in sync
206
-        // with its local key
207
-        $this->needSync[] = $relation;
208
-
209
-        return true;
210
-    }
211
-
212
-    /**
213
-     * Check if value isn't parent or root in the aggregate
214
-     *
215
-     * @param  mixed
216
-     * @return boolean|null
217
-     */
218
-    protected function isParentOrRoot($value)
219
-    {
220
-        if (!is_null($this->root)) {
221
-            $rootClass = get_class($this->root->getEntityObject());
222
-            if ($rootClass == get_class($value)) {
223
-                return true;
224
-            }
225
-        }
226
-
227
-        if (!is_null($this->parent)) {
228
-            $parentClass = get_class($this->parent->getEntityObject());
229
-            if ($parentClass == get_class($value)) {
230
-                return true;
231
-            }
232
-        }
233
-    }
234
-
235
-    /**
236
-     * Parse a 'many' relationship
237
-     *
238
-     * @param  string $relation
239
-     * @throws MappingException
240
-     * @return boolean
241
-     */
242
-    protected function parseManyRelationship($relation)
243
-    {
244
-        if (!$value = $this->parseForCommonValues($relation)) {
245
-            return true;
246
-        }
201
+		// Even if it's a single entity, we'll store it as an array
202
+		// just for consistency with other relationships
203
+		$this->relationships[$relation] = [$subAggregate];
204
+
205
+		// We always need to check a loaded relation is in sync
206
+		// with its local key
207
+		$this->needSync[] = $relation;
208
+
209
+		return true;
210
+	}
211
+
212
+	/**
213
+	 * Check if value isn't parent or root in the aggregate
214
+	 *
215
+	 * @param  mixed
216
+	 * @return boolean|null
217
+	 */
218
+	protected function isParentOrRoot($value)
219
+	{
220
+		if (!is_null($this->root)) {
221
+			$rootClass = get_class($this->root->getEntityObject());
222
+			if ($rootClass == get_class($value)) {
223
+				return true;
224
+			}
225
+		}
226
+
227
+		if (!is_null($this->parent)) {
228
+			$parentClass = get_class($this->parent->getEntityObject());
229
+			if ($parentClass == get_class($value)) {
230
+				return true;
231
+			}
232
+		}
233
+	}
234
+
235
+	/**
236
+	 * Parse a 'many' relationship
237
+	 *
238
+	 * @param  string $relation
239
+	 * @throws MappingException
240
+	 * @return boolean
241
+	 */
242
+	protected function parseManyRelationship($relation)
243
+	{
244
+		if (!$value = $this->parseForCommonValues($relation)) {
245
+			return true;
246
+		}
247 247
         
248
-        if (is_array($value) || $value instanceof Collection) {
249
-            $this->needSync[] = $relation;
250
-        }
251
-
252
-        // If the relation is a proxy, we test is the relation
253
-        // has been lazy loaded, otherwise we'll just treat
254
-        // the subset of newly added items.
255
-        if ($value instanceof CollectionProxy && $value->isProxyInitialized()) {
256
-            $this->needSync[] = $relation;
257
-            //$value = $value->getUnderlyingCollection();
258
-        }
259
-
260
-        if ($value instanceof CollectionProxy && !$value->isProxyInitialized()) {
261
-            $value = $value->getAddedItems();
262
-        }
263
-
264
-        // At this point $value should be either an array or an instance
265
-        // of a collection class.
266
-        if (!is_array($value) && !$value instanceof Collection) {
267
-            throw new MappingException("'$relation' attribute should be array() or Collection");
268
-        }
269
-
270
-        $this->relationships[$relation] = $this->createSubAggregates($value, $relation);
248
+		if (is_array($value) || $value instanceof Collection) {
249
+			$this->needSync[] = $relation;
250
+		}
251
+
252
+		// If the relation is a proxy, we test is the relation
253
+		// has been lazy loaded, otherwise we'll just treat
254
+		// the subset of newly added items.
255
+		if ($value instanceof CollectionProxy && $value->isProxyInitialized()) {
256
+			$this->needSync[] = $relation;
257
+			//$value = $value->getUnderlyingCollection();
258
+		}
259
+
260
+		if ($value instanceof CollectionProxy && !$value->isProxyInitialized()) {
261
+			$value = $value->getAddedItems();
262
+		}
263
+
264
+		// At this point $value should be either an array or an instance
265
+		// of a collection class.
266
+		if (!is_array($value) && !$value instanceof Collection) {
267
+			throw new MappingException("'$relation' attribute should be array() or Collection");
268
+		}
269
+
270
+		$this->relationships[$relation] = $this->createSubAggregates($value, $relation);
271 271
         
272
-        return true;
273
-    }
274
-
275
-    /**
276
-     * Return Entity's relationship attribute
277
-     *
278
-     * @param  string $relation
279
-     * @throws MappingException
280
-     * @return mixed
281
-     */
282
-    protected function getRelationshipValue($relation)
283
-    {
284
-        $value = $this->getEntityAttribute($relation);
285
-        //if($relation == "role") tdd($this->wrappedEntity->getEntityAttributes());
286
-        if (is_bool($value) || is_float($value) || is_int($value) || is_string($value)) {
287
-            throw new MappingException("Entity's attribute $relation should be array, object, collection or null");
288
-        }
289
-
290
-        return $value;
291
-    }
292
-
293
-    /**
294
-     * Create a child, aggregated entity
295
-     *
296
-     * @param  mixed $entities
297
-     * @param string $relation
298
-     * @return array
299
-     */
300
-    protected function createSubAggregates($entities, $relation)
301
-    {
302
-        $aggregates = [];
303
-
304
-        foreach ($entities as $entity) {
305
-            $aggregates[] = $this->createSubAggregate($entity, $relation);
306
-        }
307
-
308
-        return $aggregates;
309
-    }
310
-
311
-    /**
312
-     * Create a related subAggregate
313
-     *
314
-     * @param  mixed $entity
315
-     * @param  string $relation
316
-     * @throws MappingException
317
-     * @return self
318
-     */
319
-    protected function createSubAggregate($entity, $relation)
320
-    {
321
-        // If root isn't defined, then this is the Aggregate Root
322
-        if (is_null($this->root)) {
323
-            $root = $this;
324
-        } else {
325
-            $root = $this->root;
326
-        }
327
-
328
-        return new self($entity, $this, $relation, $root);
329
-    }
330
-
331
-    /**
332
-     * Get the Entity's primary key attribute
333
-     *
334
-     * @return string|integer
335
-     */
336
-    public function getEntityId()
337
-    {
338
-        return $this->wrappedEntity->getEntityAttribute($this->entityMap->getKeyName());
339
-    }
340
-
341
-    /**
342
-     * Get the name of the primary key
343
-     *
344
-     * @return string
345
-     */
346
-    public function getEntityKey()
347
-    {
348
-        return $this->entityMap->getKeyName();
349
-    }
350
-
351
-    /**
352
-     * Return the entity map for the current entity
353
-     *
354
-     * @return \Analogue\ORM\EntityMap
355
-     */
356
-    public function getEntityMap()
357
-    {
358
-        return $this->entityMap;
359
-    }
360
-
361
-    /**
362
-     * Return the Entity's hash $class.$id
363
-     *
364
-     * @return string
365
-     */
366
-    public function getEntityHash()
367
-    {
368
-        return $this->getEntityClass() . '.' . $this->getEntityId();
369
-    }
370
-
371
-    /**
372
-     * Get wrapped entity class
373
-     *
374
-     * @return string
375
-     */
376
-    public function getEntityClass()
377
-    {
378
-        return $this->entityMap->getClass();
379
-    }
380
-
381
-    /**
382
-     * Return the Mapper's entity cache
383
-     *
384
-     * @return \Analogue\ORM\System\EntityCache
385
-     */
386
-    protected function getEntityCache()
387
-    {
388
-        return $this->getMapper()->getEntityCache();
389
-    }
390
-
391
-    /**
392
-     * Get a relationship as an aggregated entities' array
393
-     *
394
-     * @param  string $name
395
-     * @return array
396
-     */
397
-    public function getRelationship($name)
398
-    {
399
-        if (array_key_exists($name, $this->relationships)) {
400
-            return $this->relationships[$name];
401
-        } else {
402
-            return [];
403
-        }
404
-    }
405
-
406
-    /**
407
-     * [TO IMPLEMENT]
408
-     *
409
-     * @return array
410
-     */
411
-    public function getPivotAttributes()
412
-    {
413
-        return [];
414
-    }
415
-
416
-    /**
417
-     * Get Non existing related entities from several relationships
418
-     *
419
-     * @param  array $relationships
420
-     * @return array
421
-     */
422
-    public function getNonExistingRelated(array $relationships)
423
-    {
424
-        $nonExisting = [];
425
-
426
-        foreach ($relationships as $relation) {
427
-
428
-            if ($this->hasAttribute($relation) && array_key_exists($relation, $this->relationships)) {
429
-                $nonExisting = array_merge($nonExisting, $this->getNonExistingFromRelation($relation));
430
-            }
431
-        }
432
-
433
-        return $nonExisting;
434
-    }
435
-
436
-    /**
437
-     * Get non-existing related entities from a single relation
438
-     *
439
-     * @param  string $relation
440
-     * @return array
441
-     */
442
-    protected function getNonExistingFromRelation($relation)
443
-    {
444
-        $nonExisting = [];
445
-
446
-        foreach ($this->relationships[$relation] as $aggregate) {
447
-            if (!$aggregate->exists()) {
448
-                $nonExisting[] = $aggregate;
449
-            }
450
-        }
451
-
452
-        return $nonExisting;
453
-    }
454
-
455
-    /**
456
-     * Synchronize relationships if needed
457
-     *
458
-     * @param array
459
-     * @return void
460
-     */
461
-    public function syncRelationships(array $relationships)
462
-    {
463
-        foreach ($relationships as $relation) {
464
-            if (in_array($relation, $this->needSync)) {
465
-                $this->synchronize($relation);
466
-            }
467
-        }
468
-    }
469
-
470
-    /**
471
-     * Synchronize a relationship attribute
472
-     *
473
-     * @param $relation
474
-     * @return void
475
-     */
476
-    protected function synchronize($relation)
477
-    {
478
-        $actualContent = $this->relationships[$relation];
479
-
480
-        $relationshipObject = $this->entityMap->$relation($this->getEntityObject());
481
-        $relationshipObject->setParent($this->wrappedEntity);
482
-        $relationshipObject->sync($actualContent);
483
-    }
484
-
485
-    /**
486
-     * Returns an array of Missing related Entities for the
487
-     * given $relation
488
-     *
489
-     * @param  string $relation
490
-     * @return array
491
-     */
492
-    public function getMissingEntities($relation)
493
-    {
494
-        $cachedRelations = $this->getCachedAttribute($relation);
495
-
496
-        if (!is_null($cachedRelations)) {
497
-            $missing = [];
498
-
499
-            foreach ($cachedRelations as $hash) {
500
-                if (!$this->getRelatedAggregateFromHash($hash, $relation)) {
501
-                    $missing[] = $hash;
502
-                }
503
-            }
504
-
505
-            return $missing;
506
-        } else {
507
-            return [];
508
-        }
509
-    }
272
+		return true;
273
+	}
274
+
275
+	/**
276
+	 * Return Entity's relationship attribute
277
+	 *
278
+	 * @param  string $relation
279
+	 * @throws MappingException
280
+	 * @return mixed
281
+	 */
282
+	protected function getRelationshipValue($relation)
283
+	{
284
+		$value = $this->getEntityAttribute($relation);
285
+		//if($relation == "role") tdd($this->wrappedEntity->getEntityAttributes());
286
+		if (is_bool($value) || is_float($value) || is_int($value) || is_string($value)) {
287
+			throw new MappingException("Entity's attribute $relation should be array, object, collection or null");
288
+		}
289
+
290
+		return $value;
291
+	}
292
+
293
+	/**
294
+	 * Create a child, aggregated entity
295
+	 *
296
+	 * @param  mixed $entities
297
+	 * @param string $relation
298
+	 * @return array
299
+	 */
300
+	protected function createSubAggregates($entities, $relation)
301
+	{
302
+		$aggregates = [];
303
+
304
+		foreach ($entities as $entity) {
305
+			$aggregates[] = $this->createSubAggregate($entity, $relation);
306
+		}
307
+
308
+		return $aggregates;
309
+	}
310
+
311
+	/**
312
+	 * Create a related subAggregate
313
+	 *
314
+	 * @param  mixed $entity
315
+	 * @param  string $relation
316
+	 * @throws MappingException
317
+	 * @return self
318
+	 */
319
+	protected function createSubAggregate($entity, $relation)
320
+	{
321
+		// If root isn't defined, then this is the Aggregate Root
322
+		if (is_null($this->root)) {
323
+			$root = $this;
324
+		} else {
325
+			$root = $this->root;
326
+		}
327
+
328
+		return new self($entity, $this, $relation, $root);
329
+	}
330
+
331
+	/**
332
+	 * Get the Entity's primary key attribute
333
+	 *
334
+	 * @return string|integer
335
+	 */
336
+	public function getEntityId()
337
+	{
338
+		return $this->wrappedEntity->getEntityAttribute($this->entityMap->getKeyName());
339
+	}
340
+
341
+	/**
342
+	 * Get the name of the primary key
343
+	 *
344
+	 * @return string
345
+	 */
346
+	public function getEntityKey()
347
+	{
348
+		return $this->entityMap->getKeyName();
349
+	}
350
+
351
+	/**
352
+	 * Return the entity map for the current entity
353
+	 *
354
+	 * @return \Analogue\ORM\EntityMap
355
+	 */
356
+	public function getEntityMap()
357
+	{
358
+		return $this->entityMap;
359
+	}
360
+
361
+	/**
362
+	 * Return the Entity's hash $class.$id
363
+	 *
364
+	 * @return string
365
+	 */
366
+	public function getEntityHash()
367
+	{
368
+		return $this->getEntityClass() . '.' . $this->getEntityId();
369
+	}
370
+
371
+	/**
372
+	 * Get wrapped entity class
373
+	 *
374
+	 * @return string
375
+	 */
376
+	public function getEntityClass()
377
+	{
378
+		return $this->entityMap->getClass();
379
+	}
380
+
381
+	/**
382
+	 * Return the Mapper's entity cache
383
+	 *
384
+	 * @return \Analogue\ORM\System\EntityCache
385
+	 */
386
+	protected function getEntityCache()
387
+	{
388
+		return $this->getMapper()->getEntityCache();
389
+	}
390
+
391
+	/**
392
+	 * Get a relationship as an aggregated entities' array
393
+	 *
394
+	 * @param  string $name
395
+	 * @return array
396
+	 */
397
+	public function getRelationship($name)
398
+	{
399
+		if (array_key_exists($name, $this->relationships)) {
400
+			return $this->relationships[$name];
401
+		} else {
402
+			return [];
403
+		}
404
+	}
405
+
406
+	/**
407
+	 * [TO IMPLEMENT]
408
+	 *
409
+	 * @return array
410
+	 */
411
+	public function getPivotAttributes()
412
+	{
413
+		return [];
414
+	}
415
+
416
+	/**
417
+	 * Get Non existing related entities from several relationships
418
+	 *
419
+	 * @param  array $relationships
420
+	 * @return array
421
+	 */
422
+	public function getNonExistingRelated(array $relationships)
423
+	{
424
+		$nonExisting = [];
425
+
426
+		foreach ($relationships as $relation) {
427
+
428
+			if ($this->hasAttribute($relation) && array_key_exists($relation, $this->relationships)) {
429
+				$nonExisting = array_merge($nonExisting, $this->getNonExistingFromRelation($relation));
430
+			}
431
+		}
432
+
433
+		return $nonExisting;
434
+	}
435
+
436
+	/**
437
+	 * Get non-existing related entities from a single relation
438
+	 *
439
+	 * @param  string $relation
440
+	 * @return array
441
+	 */
442
+	protected function getNonExistingFromRelation($relation)
443
+	{
444
+		$nonExisting = [];
445
+
446
+		foreach ($this->relationships[$relation] as $aggregate) {
447
+			if (!$aggregate->exists()) {
448
+				$nonExisting[] = $aggregate;
449
+			}
450
+		}
451
+
452
+		return $nonExisting;
453
+	}
454
+
455
+	/**
456
+	 * Synchronize relationships if needed
457
+	 *
458
+	 * @param array
459
+	 * @return void
460
+	 */
461
+	public function syncRelationships(array $relationships)
462
+	{
463
+		foreach ($relationships as $relation) {
464
+			if (in_array($relation, $this->needSync)) {
465
+				$this->synchronize($relation);
466
+			}
467
+		}
468
+	}
469
+
470
+	/**
471
+	 * Synchronize a relationship attribute
472
+	 *
473
+	 * @param $relation
474
+	 * @return void
475
+	 */
476
+	protected function synchronize($relation)
477
+	{
478
+		$actualContent = $this->relationships[$relation];
479
+
480
+		$relationshipObject = $this->entityMap->$relation($this->getEntityObject());
481
+		$relationshipObject->setParent($this->wrappedEntity);
482
+		$relationshipObject->sync($actualContent);
483
+	}
484
+
485
+	/**
486
+	 * Returns an array of Missing related Entities for the
487
+	 * given $relation
488
+	 *
489
+	 * @param  string $relation
490
+	 * @return array
491
+	 */
492
+	public function getMissingEntities($relation)
493
+	{
494
+		$cachedRelations = $this->getCachedAttribute($relation);
495
+
496
+		if (!is_null($cachedRelations)) {
497
+			$missing = [];
498
+
499
+			foreach ($cachedRelations as $hash) {
500
+				if (!$this->getRelatedAggregateFromHash($hash, $relation)) {
501
+					$missing[] = $hash;
502
+				}
503
+			}
504
+
505
+			return $missing;
506
+		} else {
507
+			return [];
508
+		}
509
+	}
510 510
        
511
-    /**
512
-     * Get Relationships who have dirty attributes / dirty relationships
513
-     *
514
-     * @return array
515
-     */
516
-    public function getDirtyRelationships()
517
-    {
518
-        $dirtyAggregates = [];
519
-
520
-        foreach ($this->relationships as $relation) {
521
-            foreach ($relation as $aggregate) {
522
-
523
-                if (!$aggregate->exists() || $aggregate->isDirty() || count($aggregate->getDirtyRelationships()) > 0) {
524
-                    $dirtyAggregates[] = $aggregate;
525
-                }
526
-            }
527
-        }
528
-
529
-        return $dirtyAggregates;
530
-    }
511
+	/**
512
+	 * Get Relationships who have dirty attributes / dirty relationships
513
+	 *
514
+	 * @return array
515
+	 */
516
+	public function getDirtyRelationships()
517
+	{
518
+		$dirtyAggregates = [];
519
+
520
+		foreach ($this->relationships as $relation) {
521
+			foreach ($relation as $aggregate) {
522
+
523
+				if (!$aggregate->exists() || $aggregate->isDirty() || count($aggregate->getDirtyRelationships()) > 0) {
524
+					$dirtyAggregates[] = $aggregate;
525
+				}
526
+			}
527
+		}
528
+
529
+		return $dirtyAggregates;
530
+	}
531 531
     
532
-    /**
533
-     * Compare the object's raw attributes with the record in cache
534
-     *
535
-     * @return boolean
536
-     */
537
-    public function isDirty()
538
-    {
539
-        if (count($this->getDirtyRawAttributes()) > 0) {
540
-            return true;
541
-        } else {
542
-            return false;
543
-        }
544
-    }
545
-
546
-    /**
547
-     * Get Raw Entity's attributes, as they are represented
548
-     * in the database, including value objects, foreign keys,
549
-     * and discriminator column
550
-     *
551
-     * @return array
552
-     */
553
-    public function getRawAttributes()
554
-    {
555
-        $attributes = $this->wrappedEntity->getEntityAttributes();
556
-
557
-        foreach ($this->entityMap->getRelationships() as $relation) {
558
-            unset($attributes[$relation]);
559
-        }
560
-
561
-        if($this->entityMap->getInheritanceType() == 'single_table') {
562
-            $attributes = $this->addDiscriminatorColumn($attributes);
563
-        }
564
-
565
-        $attributes = $this->flattenEmbeddables($attributes);
566
-
567
-        $foreignKeys = $this->getForeignKeyAttributes();
568
-
569
-        return $attributes + $foreignKeys;
570
-    }
571
-
572
-    /**
573
-     * Add Discriminator Column if it doesn't exist on the actual entity
574
-     * 
575
-     * @param array $attributes
576
-     * @return array
577
-     */
578
-    protected function addDiscriminatorColumn($attributes)
579
-    {
580
-        $discriminatorColumn = $this->entityMap->getDiscriminatorColumn();
581
-        $entityClass = $this->entityMap->getClass();
582
-
583
-        if(! array_key_exists($discriminatorColumn, $attributes)) {
532
+	/**
533
+	 * Compare the object's raw attributes with the record in cache
534
+	 *
535
+	 * @return boolean
536
+	 */
537
+	public function isDirty()
538
+	{
539
+		if (count($this->getDirtyRawAttributes()) > 0) {
540
+			return true;
541
+		} else {
542
+			return false;
543
+		}
544
+	}
545
+
546
+	/**
547
+	 * Get Raw Entity's attributes, as they are represented
548
+	 * in the database, including value objects, foreign keys,
549
+	 * and discriminator column
550
+	 *
551
+	 * @return array
552
+	 */
553
+	public function getRawAttributes()
554
+	{
555
+		$attributes = $this->wrappedEntity->getEntityAttributes();
556
+
557
+		foreach ($this->entityMap->getRelationships() as $relation) {
558
+			unset($attributes[$relation]);
559
+		}
560
+
561
+		if($this->entityMap->getInheritanceType() == 'single_table') {
562
+			$attributes = $this->addDiscriminatorColumn($attributes);
563
+		}
564
+
565
+		$attributes = $this->flattenEmbeddables($attributes);
566
+
567
+		$foreignKeys = $this->getForeignKeyAttributes();
568
+
569
+		return $attributes + $foreignKeys;
570
+	}
571
+
572
+	/**
573
+	 * Add Discriminator Column if it doesn't exist on the actual entity
574
+	 * 
575
+	 * @param array $attributes
576
+	 * @return array
577
+	 */
578
+	protected function addDiscriminatorColumn($attributes)
579
+	{
580
+		$discriminatorColumn = $this->entityMap->getDiscriminatorColumn();
581
+		$entityClass = $this->entityMap->getClass();
582
+
583
+		if(! array_key_exists($discriminatorColumn, $attributes)) {
584 584
             
585
-            // Use key if present in discriminatorMap
586
-            $map = $this->entityMap->getDiscriminatorColumnMap();
587
-
588
-            $type = array_search($entityClass, $map);
589
-
590
-            if($type === false) {
591
-                // Use entity FQDN if no corresponding key is set
592
-                $attributes[$discriminatorColumn] = $entityClass;
593
-            }
594
-            else {
595
-                $attributes[$discriminatorColumn] = $type;
596
-            }
597
-        }
598
-
599
-        return $attributes;
600
-    }
601
-
602
-    /**
603
-     * Convert Value Objects to raw db attributes
604
-     *
605
-     * @param  array $attributes
606
-     * @return array
607
-     */
608
-    protected function flattenEmbeddables($attributes)
609
-    {
610
-        $embeddables = $this->entityMap->getEmbeddables();
585
+			// Use key if present in discriminatorMap
586
+			$map = $this->entityMap->getDiscriminatorColumnMap();
587
+
588
+			$type = array_search($entityClass, $map);
589
+
590
+			if($type === false) {
591
+				// Use entity FQDN if no corresponding key is set
592
+				$attributes[$discriminatorColumn] = $entityClass;
593
+			}
594
+			else {
595
+				$attributes[$discriminatorColumn] = $type;
596
+			}
597
+		}
598
+
599
+		return $attributes;
600
+	}
601
+
602
+	/**
603
+	 * Convert Value Objects to raw db attributes
604
+	 *
605
+	 * @param  array $attributes
606
+	 * @return array
607
+	 */
608
+	protected function flattenEmbeddables($attributes)
609
+	{
610
+		$embeddables = $this->entityMap->getEmbeddables();
611 611
         
612
-        foreach ($embeddables as $localKey => $embed) {
613
-            // Retrieve the value object from the entity's attributes
614
-            $valueObject = $attributes[$localKey];
612
+		foreach ($embeddables as $localKey => $embed) {
613
+			// Retrieve the value object from the entity's attributes
614
+			$valueObject = $attributes[$localKey];
615 615
 
616
-            // Unset the corresponding key
617
-            unset($attributes[$localKey]);
616
+			// Unset the corresponding key
617
+			unset($attributes[$localKey]);
618 618
 
619
-            // TODO Make wrapper object compatible with value objects
620
-            $valueObjectAttributes = $valueObject->getEntityAttributes();
619
+			// TODO Make wrapper object compatible with value objects
620
+			$valueObjectAttributes = $valueObject->getEntityAttributes();
621 621
 
622
-            // Now (if setup in the entity map) we prefix the value object's
623
-            // attributes with the snake_case name of the embedded class.
624
-            $prefix = snake_case(class_basename($embed));
622
+			// Now (if setup in the entity map) we prefix the value object's
623
+			// attributes with the snake_case name of the embedded class.
624
+			$prefix = snake_case(class_basename($embed));
625 625
 
626
-            foreach ($valueObjectAttributes as $key=>$value) {
627
-                $valueObjectAttributes[$prefix . '_' . $key] = $value;
628
-                unset($valueObjectAttributes[$key]);
629
-            }
626
+			foreach ($valueObjectAttributes as $key=>$value) {
627
+				$valueObjectAttributes[$prefix . '_' . $key] = $value;
628
+				unset($valueObjectAttributes[$key]);
629
+			}
630 630
 
631
-            $attributes = array_merge($attributes, $valueObjectAttributes);
632
-        }
631
+			$attributes = array_merge($attributes, $valueObjectAttributes);
632
+		}
633 633
         
634
-        return $attributes;
635
-    }
636
-
637
-    /**
638
-     * Return's entity raw attributes in the state they were at last
639
-     * query.
640
-     *
641
-     * @param  array|null $columns
642
-     * @return array
643
-     */
644
-    protected function getCachedRawAttributes(array $columns = null)
645
-    {
646
-        $cachedAttributes = $this->getCache()->get($this->getEntityId());
647
-
648
-        if (is_null($columns)) {
649
-            return $cachedAttributes;
650
-        } else {
651
-            return array_only($cachedAttributes, $columns);
652
-        }
653
-    }
654
-
655
-    /**
656
-     * Return a single attribute from the cache
657
-     * @param  string $key
658
-     * @return mixed
659
-     */
660
-    protected function getCachedAttribute($key)
661
-    {
662
-        $cachedAttributes = $this->getCache()->get($this->getEntityId());
663
-
664
-        if (!array_key_exists($key, $cachedAttributes)) {
665
-            return null;
666
-        } else {
667
-            return $cachedAttributes[$key];
668
-        }
669
-    }
670
-
671
-    /**
672
-     * Convert related Entity's attributes to foreign keys
673
-     *
674
-     * @return array
675
-     */
676
-    protected function getForeignKeyAttributes()
677
-    {
678
-        $foreignKeys = [];
679
-
680
-        foreach ($this->entityMap->getLocalRelationships() as $relation) {
681
-            // check if relationship has been parsed, meaning it has an actual object
682
-            // in the entity's attributes
683
-            if ($this->isActualRelationships($relation)) {
684
-                $foreignKeys = $foreignKeys + $this->getForeignKeyAttributesFromRelation($relation);
685
-            }
686
-        }
687
-
688
-        if ( ! is_null($this->parent)) {
689
-            $foreignKeys = $foreignKeys + $this->getForeignKeyAttributesFromParent();
690
-        }
691
-
692
-        return $foreignKeys;
693
-    }
694
-
695
-    /**
696
-     * Return an associative array containing the key-value pair(s) from
697
-     * the related entity.
698
-     *
699
-     * @param  string $relation
700
-     * @return array
701
-     */
702
-    protected function getForeignKeyAttributesFromRelation($relation)
703
-    {
704
-        $localRelations = $this->entityMap->getLocalRelationships();
705
-
706
-        if (in_array($relation, $localRelations)) {
707
-            // Call Relationship's method
708
-            $relationship = $this->entityMap->$relation($this->getEntityObject());
709
-
710
-            $relatedAggregate = $this->relationships[$relation][0];
711
-
712
-            return $relationship->getForeignKeyValuePair($relatedAggregate->getEntityObject());
713
-        } else {
714
-            return [];
715
-        }
716
-    }
717
-
718
-    /**
719
-     * Get foreign key attribute(s) from a parent entity in this
720
-     * aggregate context
721
-     *
722
-     * @return array
723
-     */
724
-    protected function getForeignKeyAttributesFromParent()
725
-    {
726
-        $parentMap = $this->parent->getEntityMap();
727
-
728
-        $parentForeignRelations = $parentMap->getForeignRelationships();
729
-        $parentPivotRelations = $parentMap->getPivotRelationships();
730
-
731
-        // The parentRelation is the name of the relationship
732
-        // methods on the parent entity map
733
-        $parentRelation = $this->parentRelationship;
734
-
735
-        if (in_array($parentRelation, $parentForeignRelations)
736
-            && !in_array($parentRelation, $parentPivotRelations)
737
-        ) {
738
-            $parentObject = $this->parent->getEntityObject();
739
-
740
-            // Call Relationship's method on parent map
741
-            $relationship = $parentMap->$parentRelation($parentObject);
742
-
743
-            return $relationship->getForeignKeyValuePair();
744
-        } else {
745
-            return [];
746
-        }
747
-    }
748
-
749
-    /**
750
-     * Update Pivot records on loaded relationships, by comparing the
751
-     * values from the Entity Cache to the actual relationship inside
752
-     * the aggregated entity.
753
-     *
754
-     * @return void
755
-     */
756
-    public function updatePivotRecords()
757
-    {
758
-        $pivots = $this->entityMap->getPivotRelationships();
759
-
760
-        foreach ($pivots as $pivot) {
761
-            if (array_key_exists($pivot, $this->relationships)) {
762
-                $this->updatePivotRelation($pivot);
763
-            }
764
-        }
765
-    }
766
-
767
-    /**
768
-     * Update Single pivot relationship
769
-     *
770
-     * @param  string $relation
771
-     * @return void
772
-     */
773
-    protected function updatePivotRelation($relation)
774
-    {
775
-        $hashes = $this->getEntityHashesFromRelation($relation);
776
-
777
-        $cachedAttributes = $this->getCachedRawAttributes();
778
-
779
-        if (array_key_exists($relation, $cachedAttributes)) {
780
-            // Compare the two array of hashes to find out existing
781
-            // pivot records, and the ones to be created.
782
-            $new = array_diff($hashes, array_keys($cachedAttributes[$relation]));
783
-            $existing = array_intersect($hashes, array_keys($cachedAttributes[$relation]));
784
-        } else {
785
-            $existing = [];
786
-            $new = $hashes;
787
-        }
788
-
789
-        if (count($new) > 0) {
790
-            $pivots = $this->getRelatedAggregatesFromHashes($new, $relation);
791
-
792
-            $this->entityMap->$relation($this->getEntityObject())->createPivots($pivots);
793
-        }
794
-
795
-        if (count($existing) > 0) {
796
-            foreach ($existing as $pivotHash) {
797
-                $this->updatePivotIfDirty($pivotHash, $relation);
798
-            }
799
-        }
800
-    }
801
-
802
-    /**
803
-     * Compare existing pivot record in cache and update it
804
-     * if the pivot attributes are dirty
805
-     *
806
-     * @param  string $pivotHash
807
-     * @param  string $relation
808
-     * @return void
809
-     */
810
-    protected function updatePivotIfDirty($pivotHash, $relation)
811
-    {
812
-        $aggregate = $this->getRelatedAggregateFromHash($pivotHash, $relation);
813
-
814
-        if ($aggregate->hasAttribute('pivot')) {
815
-            $pivot = $aggregate->getEntityAttribute('pivot')->getEntityAttributes();
816
-
817
-            $cachedPivotAttributes = $this->getPivotAttributesFromCache($pivotHash, $relation);
818
-
819
-            $actualPivotAttributes = array_only($pivot, array_keys($cachedPivotAttributes));
820
-
821
-            $dirty = $this->getDirtyAttributes($actualPivotAttributes, $cachedPivotAttributes);
822
-
823
-            if (count($dirty) > 0) {
824
-                $id = $aggregate->getEntityId();
825
-
826
-                $this->entityMap->$relation($this->getEntityObject())->updateExistingPivot($id, $dirty);
827
-            }
828
-        }
829
-    }
830
-
831
-    /**
832
-     * Compare two attributes array and return dirty attributes
833
-     *
834
-     * @param  array $actual
835
-     * @param  array $cached
836
-     * @return array
837
-     */
838
-    protected function getDirtyAttributes(array $actual, array $cached)
839
-    {
840
-        $dirty = [];
841
-
842
-        foreach ($actual as $key => $value) {
843
-            if (!$this->originalIsNumericallyEquivalent($value, $cached[$key])) {
844
-                $dirty[$key] = $actual[$key];
845
-            }
846
-        }
847
-
848
-        return $dirty;
849
-    }
850
-
851
-    /**
852
-     *
853
-     * @param  string $pivotHash
854
-     * @param  string $relation
855
-     * @return array
856
-     */
857
-    protected function getPivotAttributesFromCache($pivotHash, $relation)
858
-    {
859
-        $cachedAttributes = $this->getCachedRawAttributes();
860
-
861
-        $cachedRelations = $cachedAttributes[$relation];
862
-
863
-        foreach ($cachedRelations as $cachedRelation) {
864
-            if ($cachedRelation == $pivotHash) {
865
-                return $cachedRelation->getPivotAttributes();
866
-            }
867
-        }
868
-    }
869
-
870
-    /**
871
-     * Returns an array of related Aggregates from its entity hashes
872
-     *
873
-     * @param  array  $hashes
874
-     * @param  string $relation
875
-     * @return array
876
-     */
877
-    protected function getRelatedAggregatesFromHashes(array $hashes, $relation)
878
-    {
879
-        $related = [];
880
-
881
-        foreach ($hashes as $hash) {
882
-            $aggregate = $this->getRelatedAggregateFromHash($hash, $relation);
883
-
884
-            if (!is_null($aggregate)) {
885
-                $related[] = $aggregate;
886
-            }
887
-        }
888
-
889
-        return $related;
890
-    }
891
-
892
-    /**
893
-     * Get related aggregate from its hash
894
-     *
895
-     * @param  string $hash
896
-     * @param  string $relation
897
-     * @return \Analogue\ORM\System\Aggregate|null
898
-     */
899
-    protected function getRelatedAggregateFromHash($hash, $relation)
900
-    {
901
-        foreach ($this->relationships[$relation] as $aggregate) {
902
-            if ($aggregate->getEntityHash() == $hash) {
903
-                return $aggregate;
904
-            }
905
-        }
906
-        return null;
907
-    }
908
-
909
-    /**
910
-     * Return an array of Entity Hashes from a specific relation
911
-     *
912
-     * @param  string $relation
913
-     * @return array
914
-     */
915
-    protected function getEntityHashesFromRelation($relation)
916
-    {
917
-        return array_map(function ($aggregate) {
918
-            return $aggregate->getEntityHash();
919
-        }, $this->relationships[$relation]);
920
-    }
921
-
922
-    /**
923
-     * Check the existence of an actual relationship
924
-     *
925
-     * @param  string $relation
926
-     * @return boolean
927
-     */
928
-    protected function isActualRelationships($relation)
929
-    {
930
-        return array_key_exists($relation, $this->relationships)
931
-            && count($this->relationships[$relation]) > 0;
932
-    }
933
-
934
-    /**
935
-     * Return cache instance for the current entity type
936
-     *
937
-     * @return \Analogue\ORM\System\EntityCache
938
-     */
939
-    protected function getCache()
940
-    {
941
-        return $this->getMapper()->getEntityCache();
942
-    }
943
-
944
-    /**
945
-     * Get Only Raw Entiy's attributes which have been modified
946
-     * since last query
947
-     *
948
-     * @return array
949
-     */
950
-    public function getDirtyRawAttributes()
951
-    {
952
-        $attributes = $this->getRawAttributes();
953
-        $cachedAttributes = $this->getCachedRawAttributes(array_keys($attributes));
954
-
955
-        $dirty = [];
956
-
957
-        foreach ($attributes as $key => $value) {
958
-            if ($this->isRelation($key) || $key == 'pivot') {
959
-                continue;
960
-            }
961
-
962
-            if (!array_key_exists($key, $cachedAttributes) && !$value instanceof Pivot) {
963
-                $dirty[$key] = $value;
964
-            } elseif ($value !== $cachedAttributes[$key] &&
965
-                !$this->originalIsNumericallyEquivalent($value, $cachedAttributes[$key])) {
966
-                $dirty[$key] = $value;
967
-            }
968
-        }
969
-
970
-        return $dirty;
971
-    }
972
-
973
-    /**
974
-     * @param $key
975
-     * @return bool
976
-     */
977
-    protected function isRelation($key)
978
-    {
979
-        return in_array($key, $this->entityMap->getRelationships());
980
-    }
981
-
982
-    /**
983
-     * Determine if the new and old values for a given key are numerically equivalent.
984
-     *
985
-     * @param $current
986
-     * @param $original
987
-     * @return boolean
988
-     */
989
-    protected function originalIsNumericallyEquivalent($current, $original)
990
-    {
991
-        return is_numeric($current) && is_numeric($original) && strcmp((string) $current, (string) $original) === 0;
992
-    }
993
-
994
-    /**
995
-     * Get the underlying entity object
996
-     *
997
-     * @return mixed
998
-     */
999
-    public function getEntityObject()
1000
-    {
1001
-        return $this->wrappedEntity->getObject();
1002
-    }
1003
-
1004
-    /**
1005
-     * Return the Mapper instance for the current Entity Type
1006
-     *
1007
-     * @return \Analogue\ORM\System\Mapper
1008
-     */
1009
-    public function getMapper()
1010
-    {
1011
-        return Manager::getMapper($this->class);
1012
-    }
1013
-
1014
-    /**
1015
-     * Check that the entity already exists in the database, by checking
1016
-     * if it has an EntityCache record
1017
-     *
1018
-     * @return boolean
1019
-     */
1020
-    public function exists()
1021
-    {
1022
-        return $this->getCache()->has($this->getEntityId());
1023
-    }
1024
-
1025
-    /**
1026
-     * Set the object attribute raw values (hydration)
1027
-     *
1028
-     * @param array $attributes
1029
-     */
1030
-    public function setEntityAttributes(array $attributes)
1031
-    {
1032
-        $this->wrappedEntity->setEntityAttributes($attributes);
1033
-    }
1034
-
1035
-    /**
1036
-     * Get the raw object's values.
1037
-     *
1038
-     * @return array
1039
-     */
1040
-    public function getEntityAttributes()
1041
-    {
1042
-        return $this->wrappedEntity->getEntityAttributes();
1043
-    }
1044
-
1045
-    /**
1046
-     * Set the raw entity attributes
1047
-     * @param string $key
1048
-     * @param string $value
1049
-     */
1050
-    public function setEntityAttribute($key, $value)
1051
-    {
1052
-        $this->wrappedEntity->setEntityAttribute($key, $value);
1053
-    }
1054
-
1055
-    /**
1056
-     * Return the entity's attribute
1057
-     * @param  string $key
1058
-     * @return mixed
1059
-     */
1060
-    public function getEntityAttribute($key)
1061
-    {
1062
-        return $this->wrappedEntity->getEntityAttribute($key);
1063
-    }
1064
-
1065
-    /**
1066
-     * Does the attribute exists on the entity
1067
-     *
1068
-     * @param  string  $key
1069
-     * @return boolean
1070
-     */
1071
-    public function hasAttribute($key)
1072
-    {
1073
-        return $this->wrappedEntity->hasAttribute($key);
1074
-    }
1075
-
1076
-    /**
1077
-     * Set the lazyloading proxies on the wrapped entity
1078
-     */
1079
-    public function setProxies()
1080
-    {
1081
-        $this->wrappedEntity->setProxies();
1082
-    }
634
+		return $attributes;
635
+	}
636
+
637
+	/**
638
+	 * Return's entity raw attributes in the state they were at last
639
+	 * query.
640
+	 *
641
+	 * @param  array|null $columns
642
+	 * @return array
643
+	 */
644
+	protected function getCachedRawAttributes(array $columns = null)
645
+	{
646
+		$cachedAttributes = $this->getCache()->get($this->getEntityId());
647
+
648
+		if (is_null($columns)) {
649
+			return $cachedAttributes;
650
+		} else {
651
+			return array_only($cachedAttributes, $columns);
652
+		}
653
+	}
654
+
655
+	/**
656
+	 * Return a single attribute from the cache
657
+	 * @param  string $key
658
+	 * @return mixed
659
+	 */
660
+	protected function getCachedAttribute($key)
661
+	{
662
+		$cachedAttributes = $this->getCache()->get($this->getEntityId());
663
+
664
+		if (!array_key_exists($key, $cachedAttributes)) {
665
+			return null;
666
+		} else {
667
+			return $cachedAttributes[$key];
668
+		}
669
+	}
670
+
671
+	/**
672
+	 * Convert related Entity's attributes to foreign keys
673
+	 *
674
+	 * @return array
675
+	 */
676
+	protected function getForeignKeyAttributes()
677
+	{
678
+		$foreignKeys = [];
679
+
680
+		foreach ($this->entityMap->getLocalRelationships() as $relation) {
681
+			// check if relationship has been parsed, meaning it has an actual object
682
+			// in the entity's attributes
683
+			if ($this->isActualRelationships($relation)) {
684
+				$foreignKeys = $foreignKeys + $this->getForeignKeyAttributesFromRelation($relation);
685
+			}
686
+		}
687
+
688
+		if ( ! is_null($this->parent)) {
689
+			$foreignKeys = $foreignKeys + $this->getForeignKeyAttributesFromParent();
690
+		}
691
+
692
+		return $foreignKeys;
693
+	}
694
+
695
+	/**
696
+	 * Return an associative array containing the key-value pair(s) from
697
+	 * the related entity.
698
+	 *
699
+	 * @param  string $relation
700
+	 * @return array
701
+	 */
702
+	protected function getForeignKeyAttributesFromRelation($relation)
703
+	{
704
+		$localRelations = $this->entityMap->getLocalRelationships();
705
+
706
+		if (in_array($relation, $localRelations)) {
707
+			// Call Relationship's method
708
+			$relationship = $this->entityMap->$relation($this->getEntityObject());
709
+
710
+			$relatedAggregate = $this->relationships[$relation][0];
711
+
712
+			return $relationship->getForeignKeyValuePair($relatedAggregate->getEntityObject());
713
+		} else {
714
+			return [];
715
+		}
716
+	}
717
+
718
+	/**
719
+	 * Get foreign key attribute(s) from a parent entity in this
720
+	 * aggregate context
721
+	 *
722
+	 * @return array
723
+	 */
724
+	protected function getForeignKeyAttributesFromParent()
725
+	{
726
+		$parentMap = $this->parent->getEntityMap();
727
+
728
+		$parentForeignRelations = $parentMap->getForeignRelationships();
729
+		$parentPivotRelations = $parentMap->getPivotRelationships();
730
+
731
+		// The parentRelation is the name of the relationship
732
+		// methods on the parent entity map
733
+		$parentRelation = $this->parentRelationship;
734
+
735
+		if (in_array($parentRelation, $parentForeignRelations)
736
+			&& !in_array($parentRelation, $parentPivotRelations)
737
+		) {
738
+			$parentObject = $this->parent->getEntityObject();
739
+
740
+			// Call Relationship's method on parent map
741
+			$relationship = $parentMap->$parentRelation($parentObject);
742
+
743
+			return $relationship->getForeignKeyValuePair();
744
+		} else {
745
+			return [];
746
+		}
747
+	}
748
+
749
+	/**
750
+	 * Update Pivot records on loaded relationships, by comparing the
751
+	 * values from the Entity Cache to the actual relationship inside
752
+	 * the aggregated entity.
753
+	 *
754
+	 * @return void
755
+	 */
756
+	public function updatePivotRecords()
757
+	{
758
+		$pivots = $this->entityMap->getPivotRelationships();
759
+
760
+		foreach ($pivots as $pivot) {
761
+			if (array_key_exists($pivot, $this->relationships)) {
762
+				$this->updatePivotRelation($pivot);
763
+			}
764
+		}
765
+	}
766
+
767
+	/**
768
+	 * Update Single pivot relationship
769
+	 *
770
+	 * @param  string $relation
771
+	 * @return void
772
+	 */
773
+	protected function updatePivotRelation($relation)
774
+	{
775
+		$hashes = $this->getEntityHashesFromRelation($relation);
776
+
777
+		$cachedAttributes = $this->getCachedRawAttributes();
778
+
779
+		if (array_key_exists($relation, $cachedAttributes)) {
780
+			// Compare the two array of hashes to find out existing
781
+			// pivot records, and the ones to be created.
782
+			$new = array_diff($hashes, array_keys($cachedAttributes[$relation]));
783
+			$existing = array_intersect($hashes, array_keys($cachedAttributes[$relation]));
784
+		} else {
785
+			$existing = [];
786
+			$new = $hashes;
787
+		}
788
+
789
+		if (count($new) > 0) {
790
+			$pivots = $this->getRelatedAggregatesFromHashes($new, $relation);
791
+
792
+			$this->entityMap->$relation($this->getEntityObject())->createPivots($pivots);
793
+		}
794
+
795
+		if (count($existing) > 0) {
796
+			foreach ($existing as $pivotHash) {
797
+				$this->updatePivotIfDirty($pivotHash, $relation);
798
+			}
799
+		}
800
+	}
801
+
802
+	/**
803
+	 * Compare existing pivot record in cache and update it
804
+	 * if the pivot attributes are dirty
805
+	 *
806
+	 * @param  string $pivotHash
807
+	 * @param  string $relation
808
+	 * @return void
809
+	 */
810
+	protected function updatePivotIfDirty($pivotHash, $relation)
811
+	{
812
+		$aggregate = $this->getRelatedAggregateFromHash($pivotHash, $relation);
813
+
814
+		if ($aggregate->hasAttribute('pivot')) {
815
+			$pivot = $aggregate->getEntityAttribute('pivot')->getEntityAttributes();
816
+
817
+			$cachedPivotAttributes = $this->getPivotAttributesFromCache($pivotHash, $relation);
818
+
819
+			$actualPivotAttributes = array_only($pivot, array_keys($cachedPivotAttributes));
820
+
821
+			$dirty = $this->getDirtyAttributes($actualPivotAttributes, $cachedPivotAttributes);
822
+
823
+			if (count($dirty) > 0) {
824
+				$id = $aggregate->getEntityId();
825
+
826
+				$this->entityMap->$relation($this->getEntityObject())->updateExistingPivot($id, $dirty);
827
+			}
828
+		}
829
+	}
830
+
831
+	/**
832
+	 * Compare two attributes array and return dirty attributes
833
+	 *
834
+	 * @param  array $actual
835
+	 * @param  array $cached
836
+	 * @return array
837
+	 */
838
+	protected function getDirtyAttributes(array $actual, array $cached)
839
+	{
840
+		$dirty = [];
841
+
842
+		foreach ($actual as $key => $value) {
843
+			if (!$this->originalIsNumericallyEquivalent($value, $cached[$key])) {
844
+				$dirty[$key] = $actual[$key];
845
+			}
846
+		}
847
+
848
+		return $dirty;
849
+	}
850
+
851
+	/**
852
+	 *
853
+	 * @param  string $pivotHash
854
+	 * @param  string $relation
855
+	 * @return array
856
+	 */
857
+	protected function getPivotAttributesFromCache($pivotHash, $relation)
858
+	{
859
+		$cachedAttributes = $this->getCachedRawAttributes();
860
+
861
+		$cachedRelations = $cachedAttributes[$relation];
862
+
863
+		foreach ($cachedRelations as $cachedRelation) {
864
+			if ($cachedRelation == $pivotHash) {
865
+				return $cachedRelation->getPivotAttributes();
866
+			}
867
+		}
868
+	}
869
+
870
+	/**
871
+	 * Returns an array of related Aggregates from its entity hashes
872
+	 *
873
+	 * @param  array  $hashes
874
+	 * @param  string $relation
875
+	 * @return array
876
+	 */
877
+	protected function getRelatedAggregatesFromHashes(array $hashes, $relation)
878
+	{
879
+		$related = [];
880
+
881
+		foreach ($hashes as $hash) {
882
+			$aggregate = $this->getRelatedAggregateFromHash($hash, $relation);
883
+
884
+			if (!is_null($aggregate)) {
885
+				$related[] = $aggregate;
886
+			}
887
+		}
888
+
889
+		return $related;
890
+	}
891
+
892
+	/**
893
+	 * Get related aggregate from its hash
894
+	 *
895
+	 * @param  string $hash
896
+	 * @param  string $relation
897
+	 * @return \Analogue\ORM\System\Aggregate|null
898
+	 */
899
+	protected function getRelatedAggregateFromHash($hash, $relation)
900
+	{
901
+		foreach ($this->relationships[$relation] as $aggregate) {
902
+			if ($aggregate->getEntityHash() == $hash) {
903
+				return $aggregate;
904
+			}
905
+		}
906
+		return null;
907
+	}
908
+
909
+	/**
910
+	 * Return an array of Entity Hashes from a specific relation
911
+	 *
912
+	 * @param  string $relation
913
+	 * @return array
914
+	 */
915
+	protected function getEntityHashesFromRelation($relation)
916
+	{
917
+		return array_map(function ($aggregate) {
918
+			return $aggregate->getEntityHash();
919
+		}, $this->relationships[$relation]);
920
+	}
921
+
922
+	/**
923
+	 * Check the existence of an actual relationship
924
+	 *
925
+	 * @param  string $relation
926
+	 * @return boolean
927
+	 */
928
+	protected function isActualRelationships($relation)
929
+	{
930
+		return array_key_exists($relation, $this->relationships)
931
+			&& count($this->relationships[$relation]) > 0;
932
+	}
933
+
934
+	/**
935
+	 * Return cache instance for the current entity type
936
+	 *
937
+	 * @return \Analogue\ORM\System\EntityCache
938
+	 */
939
+	protected function getCache()
940
+	{
941
+		return $this->getMapper()->getEntityCache();
942
+	}
943
+
944
+	/**
945
+	 * Get Only Raw Entiy's attributes which have been modified
946
+	 * since last query
947
+	 *
948
+	 * @return array
949
+	 */
950
+	public function getDirtyRawAttributes()
951
+	{
952
+		$attributes = $this->getRawAttributes();
953
+		$cachedAttributes = $this->getCachedRawAttributes(array_keys($attributes));
954
+
955
+		$dirty = [];
956
+
957
+		foreach ($attributes as $key => $value) {
958
+			if ($this->isRelation($key) || $key == 'pivot') {
959
+				continue;
960
+			}
961
+
962
+			if (!array_key_exists($key, $cachedAttributes) && !$value instanceof Pivot) {
963
+				$dirty[$key] = $value;
964
+			} elseif ($value !== $cachedAttributes[$key] &&
965
+				!$this->originalIsNumericallyEquivalent($value, $cachedAttributes[$key])) {
966
+				$dirty[$key] = $value;
967
+			}
968
+		}
969
+
970
+		return $dirty;
971
+	}
972
+
973
+	/**
974
+	 * @param $key
975
+	 * @return bool
976
+	 */
977
+	protected function isRelation($key)
978
+	{
979
+		return in_array($key, $this->entityMap->getRelationships());
980
+	}
981
+
982
+	/**
983
+	 * Determine if the new and old values for a given key are numerically equivalent.
984
+	 *
985
+	 * @param $current
986
+	 * @param $original
987
+	 * @return boolean
988
+	 */
989
+	protected function originalIsNumericallyEquivalent($current, $original)
990
+	{
991
+		return is_numeric($current) && is_numeric($original) && strcmp((string) $current, (string) $original) === 0;
992
+	}
993
+
994
+	/**
995
+	 * Get the underlying entity object
996
+	 *
997
+	 * @return mixed
998
+	 */
999
+	public function getEntityObject()
1000
+	{
1001
+		return $this->wrappedEntity->getObject();
1002
+	}
1003
+
1004
+	/**
1005
+	 * Return the Mapper instance for the current Entity Type
1006
+	 *
1007
+	 * @return \Analogue\ORM\System\Mapper
1008
+	 */
1009
+	public function getMapper()
1010
+	{
1011
+		return Manager::getMapper($this->class);
1012
+	}
1013
+
1014
+	/**
1015
+	 * Check that the entity already exists in the database, by checking
1016
+	 * if it has an EntityCache record
1017
+	 *
1018
+	 * @return boolean
1019
+	 */
1020
+	public function exists()
1021
+	{
1022
+		return $this->getCache()->has($this->getEntityId());
1023
+	}
1024
+
1025
+	/**
1026
+	 * Set the object attribute raw values (hydration)
1027
+	 *
1028
+	 * @param array $attributes
1029
+	 */
1030
+	public function setEntityAttributes(array $attributes)
1031
+	{
1032
+		$this->wrappedEntity->setEntityAttributes($attributes);
1033
+	}
1034
+
1035
+	/**
1036
+	 * Get the raw object's values.
1037
+	 *
1038
+	 * @return array
1039
+	 */
1040
+	public function getEntityAttributes()
1041
+	{
1042
+		return $this->wrappedEntity->getEntityAttributes();
1043
+	}
1044
+
1045
+	/**
1046
+	 * Set the raw entity attributes
1047
+	 * @param string $key
1048
+	 * @param string $value
1049
+	 */
1050
+	public function setEntityAttribute($key, $value)
1051
+	{
1052
+		$this->wrappedEntity->setEntityAttribute($key, $value);
1053
+	}
1054
+
1055
+	/**
1056
+	 * Return the entity's attribute
1057
+	 * @param  string $key
1058
+	 * @return mixed
1059
+	 */
1060
+	public function getEntityAttribute($key)
1061
+	{
1062
+		return $this->wrappedEntity->getEntityAttribute($key);
1063
+	}
1064
+
1065
+	/**
1066
+	 * Does the attribute exists on the entity
1067
+	 *
1068
+	 * @param  string  $key
1069
+	 * @return boolean
1070
+	 */
1071
+	public function hasAttribute($key)
1072
+	{
1073
+		return $this->wrappedEntity->hasAttribute($key);
1074
+	}
1075
+
1076
+	/**
1077
+	 * Set the lazyloading proxies on the wrapped entity
1078
+	 */
1079
+	public function setProxies()
1080
+	{
1081
+		$this->wrappedEntity->setProxies();
1082
+	}
1083 1083
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -365,7 +365,7 @@  discard block
 block discarded – undo
365 365
      */
366 366
     public function getEntityHash()
367 367
     {
368
-        return $this->getEntityClass() . '.' . $this->getEntityId();
368
+        return $this->getEntityClass().'.'.$this->getEntityId();
369 369
     }
370 370
 
371 371
     /**
@@ -558,7 +558,7 @@  discard block
 block discarded – undo
558 558
             unset($attributes[$relation]);
559 559
         }
560 560
 
561
-        if($this->entityMap->getInheritanceType() == 'single_table') {
561
+        if ($this->entityMap->getInheritanceType() == 'single_table') {
562 562
             $attributes = $this->addDiscriminatorColumn($attributes);
563 563
         }
564 564
 
@@ -580,14 +580,14 @@  discard block
 block discarded – undo
580 580
         $discriminatorColumn = $this->entityMap->getDiscriminatorColumn();
581 581
         $entityClass = $this->entityMap->getClass();
582 582
 
583
-        if(! array_key_exists($discriminatorColumn, $attributes)) {
583
+        if (!array_key_exists($discriminatorColumn, $attributes)) {
584 584
             
585 585
             // Use key if present in discriminatorMap
586 586
             $map = $this->entityMap->getDiscriminatorColumnMap();
587 587
 
588 588
             $type = array_search($entityClass, $map);
589 589
 
590
-            if($type === false) {
590
+            if ($type === false) {
591 591
                 // Use entity FQDN if no corresponding key is set
592 592
                 $attributes[$discriminatorColumn] = $entityClass;
593 593
             }
@@ -624,7 +624,7 @@  discard block
 block discarded – undo
624 624
             $prefix = snake_case(class_basename($embed));
625 625
 
626 626
             foreach ($valueObjectAttributes as $key=>$value) {
627
-                $valueObjectAttributes[$prefix . '_' . $key] = $value;
627
+                $valueObjectAttributes[$prefix.'_'.$key] = $value;
628 628
                 unset($valueObjectAttributes[$key]);
629 629
             }
630 630
 
@@ -685,7 +685,7 @@  discard block
 block discarded – undo
685 685
             }
686 686
         }
687 687
 
688
-        if ( ! is_null($this->parent)) {
688
+        if (!is_null($this->parent)) {
689 689
             $foreignKeys = $foreignKeys + $this->getForeignKeyAttributesFromParent();
690 690
         }
691 691
 
@@ -914,7 +914,7 @@  discard block
 block discarded – undo
914 914
      */
915 915
     protected function getEntityHashesFromRelation($relation)
916 916
     {
917
-        return array_map(function ($aggregate) {
917
+        return array_map(function($aggregate) {
918 918
             return $aggregate->getEntityHash();
919 919
         }, $this->relationships[$relation]);
920 920
     }
Please login to merge, or discard this patch.
src/System/Proxies/ProxyFactory.php 2 patches
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -20,17 +20,17 @@  discard block
 block discarded – undo
20 20
 		$entityMap = Manager::getMapper($entity)->getEntityMap();
21 21
 
22 22
 		$singleRelations = $entityMap->getSingleRelationships();
23
-        $manyRelations = $entityMap->getManyRelationships();
23
+		$manyRelations = $entityMap->getManyRelationships();
24 24
 
25
-        if (in_array($relation, $singleRelations)) {
26
-        	return $this->makeEntityProxy($entity, $relation, $class);
27
-        }
25
+		if (in_array($relation, $singleRelations)) {
26
+			return $this->makeEntityProxy($entity, $relation, $class);
27
+		}
28 28
 
29
-        if (in_array($relation, $manyRelations)) {
30
-        	return new CollectionProxy($entity, $relation);
31
-        }
29
+		if (in_array($relation, $manyRelations)) {
30
+			return new CollectionProxy($entity, $relation);
31
+		}
32 32
 
33
-        throw new MappingException('Could not identity relation '.$relation);
33
+		throw new MappingException('Could not identity relation '.$relation);
34 34
 	}
35 35
 
36 36
 	/**  
@@ -50,10 +50,10 @@  discard block
 block discarded – undo
50 50
 
51 51
 			$entityMap = Manager::getMapper($entity)->getEntityMap();
52 52
 
53
-        	$wrappedObject = $entityMap->$relation($entity)->getResults($relation);
53
+			$wrappedObject = $entityMap->$relation($entity)->getResults($relation);
54 54
 
55
-		    $initializer   = null; // disable initialization
56
-		    return true; // confirm that initialization occurred correctly
55
+			$initializer   = null; // disable initialization
56
+			return true; // confirm that initialization occurred correctly
57 57
 		};
58 58
 
59 59
 		return $factory->createProxy($class, $initializer);
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -46,13 +46,13 @@
 block discarded – undo
46 46
 	{
47 47
 		$factory = new LazyLoadingValueHolderFactory();
48 48
 	 
49
-		$initializer = function (& $wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, & $initializer) use ($entity, $relation) {
49
+		$initializer = function(& $wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, & $initializer) use ($entity, $relation) {
50 50
 
51 51
 			$entityMap = Manager::getMapper($entity)->getEntityMap();
52 52
 
53 53
         	$wrappedObject = $entityMap->$relation($entity)->getResults($relation);
54 54
 
55
-		    $initializer   = null; // disable initialization
55
+		    $initializer = null; // disable initialization
56 56
 		    return true; // confirm that initialization occurred correctly
57 57
 		};
58 58
 
Please login to merge, or discard this patch.
src/MappableTrait.php 1 patch
Indentation   +55 added lines, -55 removed lines patch added patch discarded remove patch
@@ -8,63 +8,63 @@
 block discarded – undo
8 8
  */
9 9
 trait MappableTrait
10 10
 {
11
-    /**
12
-     * The Entity's Attributes
13
-     * @var array
14
-     */
15
-    //protected $attributes = [];
11
+	/**
12
+	 * The Entity's Attributes
13
+	 * @var array
14
+	 */
15
+	//protected $attributes = [];
16 16
 
17
-    /**
18
-     * Method used by the mapper to set the object
19
-     * attribute raw values (hydration)
20
-     *
21
-     * @param array $attributes
22
-     *
23
-     * @return void
24
-     */
25
-    public function setEntityAttributes(array $attributes)
26
-    {
27
-        $this->attributes = $attributes;
28
-    }
17
+	/**
18
+	 * Method used by the mapper to set the object
19
+	 * attribute raw values (hydration)
20
+	 *
21
+	 * @param array $attributes
22
+	 *
23
+	 * @return void
24
+	 */
25
+	public function setEntityAttributes(array $attributes)
26
+	{
27
+		$this->attributes = $attributes;
28
+	}
29 29
 
30
-    /**
31
-     * Method used by the mapper to get the
32
-     * raw object's values.
33
-     *
34
-     * @return array
35
-     */
36
-    public function getEntityAttributes()
37
-    {
38
-        return $this->attributes;
39
-    }
30
+	/**
31
+	 * Method used by the mapper to get the
32
+	 * raw object's values.
33
+	 *
34
+	 * @return array
35
+	 */
36
+	public function getEntityAttributes()
37
+	{
38
+		return $this->attributes;
39
+	}
40 40
 
41
-    /**
42
-     * Method used by the mapper to set raw
43
-     * key-value pair
44
-     *
45
-     * @param string $key
46
-     * @param string $value
47
-     *
48
-     * @return void
49
-     */
50
-    public function setEntityAttribute($key, $value)
51
-    {
52
-        $this->attributes[$key] = $value;
53
-    }
41
+	/**
42
+	 * Method used by the mapper to set raw
43
+	 * key-value pair
44
+	 *
45
+	 * @param string $key
46
+	 * @param string $value
47
+	 *
48
+	 * @return void
49
+	 */
50
+	public function setEntityAttribute($key, $value)
51
+	{
52
+		$this->attributes[$key] = $value;
53
+	}
54 54
 
55
-    /**
56
-     * Method used by the mapper to get single
57
-     * key-value pair
58
-     *
59
-     * @param  string $key
60
-     * @return mixed|null
61
-     */
62
-    public function getEntityAttribute($key)
63
-    {
64
-        if (array_key_exists($key, $this->attributes)) {
65
-            return $this->attributes[$key];
66
-        } else {
67
-            return null;
68
-        }
69
-    }
55
+	/**
56
+	 * Method used by the mapper to get single
57
+	 * key-value pair
58
+	 *
59
+	 * @param  string $key
60
+	 * @return mixed|null
61
+	 */
62
+	public function getEntityAttribute($key)
63
+	{
64
+		if (array_key_exists($key, $this->attributes)) {
65
+			return $this->attributes[$key];
66
+		} else {
67
+			return null;
68
+		}
69
+	}
70 70
 }
Please login to merge, or discard this patch.