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