Completed
Branch 5.3 (f8a22c)
by Rémi
08:52
created
src/Plugins/Timestamps/TimestampsPlugin.php 2 patches
Indentation   +39 added lines, -39 removed lines patch added patch discarded remove patch
@@ -12,55 +12,55 @@
 block discarded – undo
12 12
  */
13 13
 class TimestampsPlugin extends AnaloguePlugin
14 14
 {
15
-    /**
16
-     * Register the plugin
17
-     *
18
-     * @throws \Exception
19
-     * @return void
20
-     */
21
-    public function register()
22
-    {
23
-        $this->manager->registerGlobalEvent('initialized', function (Mapper $mapper) {
24
-            $entityMap = $mapper->getEntityMap();
15
+	/**
16
+	 * Register the plugin
17
+	 *
18
+	 * @throws \Exception
19
+	 * @return void
20
+	 */
21
+	public function register()
22
+	{
23
+		$this->manager->registerGlobalEvent('initialized', function (Mapper $mapper) {
24
+			$entityMap = $mapper->getEntityMap();
25 25
 
26
-            if ($entityMap->usesTimestamps()) {
27
-                $mapper->registerEvent('creating', function ($entity) use ($entityMap) {
26
+			if ($entityMap->usesTimestamps()) {
27
+				$mapper->registerEvent('creating', function ($entity) use ($entityMap) {
28 28
 
29
-                    $factory = new Factory;
30
-                    $wrappedEntity = $factory->make($entity);
29
+					$factory = new Factory;
30
+					$wrappedEntity = $factory->make($entity);
31 31
 
32
-                    $createdAtField = $entityMap->getCreatedAtColumn();
33
-                    $updatedAtField = $entityMap->getUpdatedAtColumn();
32
+					$createdAtField = $entityMap->getCreatedAtColumn();
33
+					$updatedAtField = $entityMap->getUpdatedAtColumn();
34 34
 
35
-                    $time = new Carbon;
35
+					$time = new Carbon;
36 36
 
37
-                    $wrappedEntity->setEntityAttribute($createdAtField, $time);
38
-                    $wrappedEntity->setEntityAttribute($updatedAtField, $time);
37
+					$wrappedEntity->setEntityAttribute($createdAtField, $time);
38
+					$wrappedEntity->setEntityAttribute($updatedAtField, $time);
39 39
 
40
-                });
40
+				});
41 41
 
42
-                $mapper->registerEvent('updating', function ($entity) use ($entityMap) {
42
+				$mapper->registerEvent('updating', function ($entity) use ($entityMap) {
43 43
 
44
-                    $factory = new Factory;
45
-                    $wrappedEntity = $factory->make($entity);
44
+					$factory = new Factory;
45
+					$wrappedEntity = $factory->make($entity);
46 46
 
47
-                    $updatedAtField = $entityMap->getUpdatedAtColumn();
47
+					$updatedAtField = $entityMap->getUpdatedAtColumn();
48 48
 
49
-                    $time = new Carbon;
49
+					$time = new Carbon;
50 50
 
51
-                    $wrappedEntity->setEntityAttribute($updatedAtField, $time);
52
-                });
53
-            }
54
-        });
55
-    }
51
+					$wrappedEntity->setEntityAttribute($updatedAtField, $time);
52
+				});
53
+			}
54
+		});
55
+	}
56 56
 
57
-    /**
58
-     * Get custom events provided by the plugin
59
-     *
60
-     * @return array
61
-     */
62
-    public function getCustomEvents()
63
-    {
64
-        return [];
65
-    }
57
+	/**
58
+	 * Get custom events provided by the plugin
59
+	 *
60
+	 * @return array
61
+	 */
62
+	public function getCustomEvents()
63
+	{
64
+		return [];
65
+	}
66 66
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -20,11 +20,11 @@  discard block
 block discarded – undo
20 20
      */
21 21
     public function register()
22 22
     {
23
-        $this->manager->registerGlobalEvent('initialized', function (Mapper $mapper) {
23
+        $this->manager->registerGlobalEvent('initialized', function(Mapper $mapper) {
24 24
             $entityMap = $mapper->getEntityMap();
25 25
 
26 26
             if ($entityMap->usesTimestamps()) {
27
-                $mapper->registerEvent('creating', function ($entity) use ($entityMap) {
27
+                $mapper->registerEvent('creating', function($entity) use ($entityMap) {
28 28
 
29 29
                     $factory = new Factory;
30 30
                     $wrappedEntity = $factory->make($entity);
@@ -39,7 +39,7 @@  discard block
 block discarded – undo
39 39
 
40 40
                 });
41 41
 
42
-                $mapper->registerEvent('updating', function ($entity) use ($entityMap) {
42
+                $mapper->registerEvent('updating', function($entity) use ($entityMap) {
43 43
 
44 44
                     $factory = new Factory;
45 45
                     $wrappedEntity = $factory->make($entity);
Please login to merge, or discard this patch.
src/Plugins/AnaloguePlugin.php 1 patch
Indentation   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -6,33 +6,33 @@
 block discarded – undo
6 6
 
7 7
 abstract class AnaloguePlugin implements AnaloguePluginInterface
8 8
 {
9
-    /**
10
-     * Manager instance
11
-     *
12
-     * @var Manager
13
-     */
14
-    protected $manager;
9
+	/**
10
+	 * Manager instance
11
+	 *
12
+	 * @var Manager
13
+	 */
14
+	protected $manager;
15 15
 
16
-    /**
17
-     * AnaloguePlugin constructor.
18
-     * @param Manager $manager
19
-     */
20
-    public function __construct(Manager $manager)
21
-    {
22
-        $this->manager = $manager;
23
-    }
16
+	/**
17
+	 * AnaloguePlugin constructor.
18
+	 * @param Manager $manager
19
+	 */
20
+	public function __construct(Manager $manager)
21
+	{
22
+		$this->manager = $manager;
23
+	}
24 24
 
25
-    /**
26
-     * Boot the plugin
27
-     *
28
-     * @return void
29
-     */
30
-    abstract public function register();
25
+	/**
26
+	 * Boot the plugin
27
+	 *
28
+	 * @return void
29
+	 */
30
+	abstract public function register();
31 31
 
32
-    /**
33
-     * Get custom events provided by the plugin
34
-     *
35
-     * @return array
36
-     */
37
-    abstract public function getCustomEvents();
32
+	/**
33
+	 * Get custom events provided by the plugin
34
+	 *
35
+	 * @return array
36
+	 */
37
+	abstract public function getCustomEvents();
38 38
 }
Please login to merge, or discard this patch.
src/Repository.php 2 patches
Indentation   +116 added lines, -116 removed lines patch added patch discarded remove patch
@@ -15,129 +15,129 @@
 block discarded – undo
15 15
  */
16 16
 class Repository
17 17
 {
18
-    /**
19
-     * The mapper object for the corresponding entity
20
-     *
21
-     * @var \Analogue\ORM\System\Mapper
22
-     */
23
-    protected $mapper;
18
+	/**
19
+	 * The mapper object for the corresponding entity
20
+	 *
21
+	 * @var \Analogue\ORM\System\Mapper
22
+	 */
23
+	protected $mapper;
24 24
 
25
-    /**
26
-     * To build a repository, either provide :
27
-     *
28
-     * - Mappable object's class name as a string
29
-     * - Mappable object instance
30
-     * - Instance of mapper
31
-     *
32
-     * @param  Mapper         $mapper
33
-     * @param  EntityMap|null $entityMap (optional)
34
-     * @throws \InvalidArgumentException
35
-     * @throws MappingException
36
-     */
37
-    public function __construct($mapper, EntityMap $entityMap = null)
38
-    {
39
-        if ($mapper instanceof Mappable || is_string($mapper)) {
40
-            $this->mapper = Manager::getMapper($mapper, $entityMap);
41
-        } elseif ($mapper instanceof Mapper) {
42
-            $this->mapper = $mapper;
43
-        } else {
44
-            new InvalidArgumentException('Repository class constructor need a valid Mapper or Mappable object.');
45
-        }
46
-    }
25
+	/**
26
+	 * To build a repository, either provide :
27
+	 *
28
+	 * - Mappable object's class name as a string
29
+	 * - Mappable object instance
30
+	 * - Instance of mapper
31
+	 *
32
+	 * @param  Mapper         $mapper
33
+	 * @param  EntityMap|null $entityMap (optional)
34
+	 * @throws \InvalidArgumentException
35
+	 * @throws MappingException
36
+	 */
37
+	public function __construct($mapper, EntityMap $entityMap = null)
38
+	{
39
+		if ($mapper instanceof Mappable || is_string($mapper)) {
40
+			$this->mapper = Manager::getMapper($mapper, $entityMap);
41
+		} elseif ($mapper instanceof Mapper) {
42
+			$this->mapper = $mapper;
43
+		} else {
44
+			new InvalidArgumentException('Repository class constructor need a valid Mapper or Mappable object.');
45
+		}
46
+	}
47 47
 
48
-    /**
49
-     * Return all Entities from database
50
-     *
51
-     * @return \Analogue\ORM\EntityCollection
52
-     */
53
-    public function all()
54
-    {
55
-        return $this->mapper->get();
56
-    }
48
+	/**
49
+	 * Return all Entities from database
50
+	 *
51
+	 * @return \Analogue\ORM\EntityCollection
52
+	 */
53
+	public function all()
54
+	{
55
+		return $this->mapper->get();
56
+	}
57 57
     
58
-    /**
59
-     * Fetch a record from the database
60
-     * @param  integer $id
61
-     * @return \Analogue\ORM\Mappable
62
-     */
63
-    public function find($id)
64
-    {
65
-        return $this->mapper->find($id);
66
-    }
58
+	/**
59
+	 * Fetch a record from the database
60
+	 * @param  integer $id
61
+	 * @return \Analogue\ORM\Mappable
62
+	 */
63
+	public function find($id)
64
+	{
65
+		return $this->mapper->find($id);
66
+	}
67 67
 
68
-    /**
69
-     * Get the first entity matching the given attributes.
70
-     *
71
-     * @param  array  $attributes
72
-     * @return \Analogue\ORM\Mappable|null
73
-     */
74
-    public function firstMatching(array $attributes)
75
-    {
76
-        return $this->mapper->where($attributes)->first();
77
-    }
68
+	/**
69
+	 * Get the first entity matching the given attributes.
70
+	 *
71
+	 * @param  array  $attributes
72
+	 * @return \Analogue\ORM\Mappable|null
73
+	 */
74
+	public function firstMatching(array $attributes)
75
+	{
76
+		return $this->mapper->where($attributes)->first();
77
+	}
78 78
 
79
-    /**
80
-     * Return all the entities matching the given attributes
81
-     *
82
-     * @param array $attributes
83
-     * @return \Analogue\ORM\EntityCollection
84
-     */
85
-    public function allMatching(array $attributes)
86
-    {
87
-        return $this->mapper->where($attributes)->get();
88
-    }
79
+	/**
80
+	 * Return all the entities matching the given attributes
81
+	 *
82
+	 * @param array $attributes
83
+	 * @return \Analogue\ORM\EntityCollection
84
+	 */
85
+	public function allMatching(array $attributes)
86
+	{
87
+		return $this->mapper->where($attributes)->get();
88
+	}
89 89
 
90
-    /**
91
-     * Return a paginator instance on the EntityCollection
92
-     *
93
-     * @param int|null $perPage number of item per page (fallback on default setup in entity map)
94
-     * @return \Illuminate\Pagination\LengthAwarePaginator
95
-     */
96
-    public function paginate($perPage = null)
97
-    {
98
-        return $this->mapper->paginate($perPage);
99
-    }
90
+	/**
91
+	 * Return a paginator instance on the EntityCollection
92
+	 *
93
+	 * @param int|null $perPage number of item per page (fallback on default setup in entity map)
94
+	 * @return \Illuminate\Pagination\LengthAwarePaginator
95
+	 */
96
+	public function paginate($perPage = null)
97
+	{
98
+		return $this->mapper->paginate($perPage);
99
+	}
100 100
 
101
-    /**
102
-     * Delete an entity or an entity collection from the database
103
-     *
104
-     * @param  Mappable|EntityCollection $entity
105
-     * @throws MappingException
106
-     * @throws \InvalidArgumentException
107
-     * @return \Illuminate\Support\Collection|null
108
-     */
109
-    public function delete($entity)
110
-    {
111
-        return $this->mapper->delete($entity);
112
-    }
101
+	/**
102
+	 * Delete an entity or an entity collection from the database
103
+	 *
104
+	 * @param  Mappable|EntityCollection $entity
105
+	 * @throws MappingException
106
+	 * @throws \InvalidArgumentException
107
+	 * @return \Illuminate\Support\Collection|null
108
+	 */
109
+	public function delete($entity)
110
+	{
111
+		return $this->mapper->delete($entity);
112
+	}
113 113
 
114
-    /**
115
-     * Persist an entity or an entity collection in the database.
116
-     *
117
-     * @param  Mappable|EntityCollection|array $entity
118
-     * @throws MappingException
119
-     * @throws \InvalidArgumentException
120
-     * @return Mappable|EntityCollection|array
121
-     */
122
-    public function store($entity)
123
-    {
124
-        return $this->mapper->store($entity);
125
-    }
114
+	/**
115
+	 * Persist an entity or an entity collection in the database.
116
+	 *
117
+	 * @param  Mappable|EntityCollection|array $entity
118
+	 * @throws MappingException
119
+	 * @throws \InvalidArgumentException
120
+	 * @return Mappable|EntityCollection|array
121
+	 */
122
+	public function store($entity)
123
+	{
124
+		return $this->mapper->store($entity);
125
+	}
126 126
 
127
-    /**
128
-     * Make custom mapper custom commands available in repository
129
-     *
130
-     * @param  string $method
131
-     * @param  array  $parameters
132
-     * @throws Exception
133
-     * @return mixed
134
-     */
135
-    public function __call($method, $parameters)
136
-    {
137
-        if ($this->mapper->hasCustomCommand($method)) {
138
-            call_user_func_array([$this->mapper, $method], $parameters);
139
-        } else {
140
-            throw new Exception("No method $method on " . get_class($this));
141
-        }
142
-    }
127
+	/**
128
+	 * Make custom mapper custom commands available in repository
129
+	 *
130
+	 * @param  string $method
131
+	 * @param  array  $parameters
132
+	 * @throws Exception
133
+	 * @return mixed
134
+	 */
135
+	public function __call($method, $parameters)
136
+	{
137
+		if ($this->mapper->hasCustomCommand($method)) {
138
+			call_user_func_array([$this->mapper, $method], $parameters);
139
+		} else {
140
+			throw new Exception("No method $method on " . get_class($this));
141
+		}
142
+	}
143 143
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -137,7 +137,7 @@
 block discarded – undo
137 137
         if ($this->mapper->hasCustomCommand($method)) {
138 138
             call_user_func_array([$this->mapper, $method], $parameters);
139 139
         } else {
140
-            throw new Exception("No method $method on " . get_class($this));
140
+            throw new Exception("No method $method on ".get_class($this));
141 141
         }
142 142
     }
143 143
 }
Please login to merge, or discard this patch.
src/MappableTrait.php 1 patch
Indentation   +55 added lines, -55 removed lines patch added patch discarded remove patch
@@ -8,63 +8,63 @@
 block discarded – undo
8 8
  */
9 9
 trait MappableTrait
10 10
 {
11
-    /**
12
-     * The Entity's Attributes
13
-     * @var array
14
-     */
15
-    protected $attributes = [];
11
+	/**
12
+	 * The Entity's Attributes
13
+	 * @var array
14
+	 */
15
+	protected $attributes = [];
16 16
 
17
-    /**
18
-     * Method used by the mapper to set the object
19
-     * attribute raw values (hydration)
20
-     *
21
-     * @param array $attributes
22
-     *
23
-     * @return void
24
-     */
25
-    public function setEntityAttributes(array $attributes)
26
-    {
27
-        $this->attributes = $attributes;
28
-    }
17
+	/**
18
+	 * Method used by the mapper to set the object
19
+	 * attribute raw values (hydration)
20
+	 *
21
+	 * @param array $attributes
22
+	 *
23
+	 * @return void
24
+	 */
25
+	public function setEntityAttributes(array $attributes)
26
+	{
27
+		$this->attributes = $attributes;
28
+	}
29 29
 
30
-    /**
31
-     * Method used by the mapper to get the
32
-     * raw object's values.
33
-     *
34
-     * @return array
35
-     */
36
-    public function getEntityAttributes()
37
-    {
38
-        return $this->attributes;
39
-    }
30
+	/**
31
+	 * Method used by the mapper to get the
32
+	 * raw object's values.
33
+	 *
34
+	 * @return array
35
+	 */
36
+	public function getEntityAttributes()
37
+	{
38
+		return $this->attributes;
39
+	}
40 40
 
41
-    /**
42
-     * Method used by the mapper to set raw
43
-     * key-value pair
44
-     *
45
-     * @param string $key
46
-     * @param string $value
47
-     *
48
-     * @return void
49
-     */
50
-    public function setEntityAttribute($key, $value)
51
-    {
52
-        $this->attributes[$key] = $value;
53
-    }
41
+	/**
42
+	 * Method used by the mapper to set raw
43
+	 * key-value pair
44
+	 *
45
+	 * @param string $key
46
+	 * @param string $value
47
+	 *
48
+	 * @return void
49
+	 */
50
+	public function setEntityAttribute($key, $value)
51
+	{
52
+		$this->attributes[$key] = $value;
53
+	}
54 54
 
55
-    /**
56
-     * Method used by the mapper to get single
57
-     * key-value pair
58
-     *
59
-     * @param  string $key
60
-     * @return mixed|null
61
-     */
62
-    public function getEntityAttribute($key)
63
-    {
64
-        if (array_key_exists($key, $this->attributes)) {
65
-            return $this->attributes[$key];
66
-        } else {
67
-            return null;
68
-        }
69
-    }
55
+	/**
56
+	 * Method used by the mapper to get single
57
+	 * key-value pair
58
+	 *
59
+	 * @param  string $key
60
+	 * @return mixed|null
61
+	 */
62
+	public function getEntityAttribute($key)
63
+	{
64
+		if (array_key_exists($key, $this->attributes)) {
65
+			return $this->attributes[$key];
66
+		} else {
67
+			return null;
68
+		}
69
+	}
70 70
 }
Please login to merge, or discard this patch.
src/Exceptions/EntityNotFoundException.php 1 patch
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -6,35 +6,35 @@
 block discarded – undo
6 6
 
7 7
 class EntityNotFoundException extends RuntimeException
8 8
 {
9
-    /**
10
-     * Name of the affected Entity Map.
11
-     *
12
-     * @var string
13
-     */
14
-    protected $entity;
9
+	/**
10
+	 * Name of the affected Entity Map.
11
+	 *
12
+	 * @var string
13
+	 */
14
+	protected $entity;
15 15
 
16
-    /**
17
-     * Set the affected Entity Map.
18
-     *
19
-     * @param  string   $entity
20
-     * @return $this
21
-     */
22
-    public function setEntity($entity)
23
-    {
24
-        $this->entity = $entity;
16
+	/**
17
+	 * Set the affected Entity Map.
18
+	 *
19
+	 * @param  string   $entity
20
+	 * @return $this
21
+	 */
22
+	public function setEntity($entity)
23
+	{
24
+		$this->entity = $entity;
25 25
 
26
-        $this->message = "No query results for entity [{$entity}].";
26
+		$this->message = "No query results for entity [{$entity}].";
27 27
 
28
-        return $this;
29
-    }
28
+		return $this;
29
+	}
30 30
 
31
-    /**
32
-     * Get the affected Entity.
33
-     *
34
-     * @return string
35
-     */
36
-    public function getEntity()
37
-    {
38
-        return $this->entity;
39
-    }
31
+	/**
32
+	 * Get the affected Entity.
33
+	 *
34
+	 * @return string
35
+	 */
36
+	public function getEntity()
37
+	{
38
+		return $this->entity;
39
+	}
40 40
 }
Please login to merge, or discard this patch.
src/EntityMap.php 2 patches
Spacing   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -393,7 +393,7 @@  discard block
 block discarded – undo
393 393
         if (!is_null($this->sequence)) {
394 394
             return $this->sequence;
395 395
         } else {
396
-            return $this->getTable() . '_id_seq';
396
+            return $this->getTable().'_id_seq';
397 397
         }
398 398
     }
399 399
 
@@ -563,7 +563,7 @@  discard block
 block discarded – undo
563 563
      */
564 564
     public function getQualifiedKeyName()
565 565
     {
566
-        return $this->getTable() . '.' . $this->getKeyName();
566
+        return $this->getTable().'.'.$this->getKeyName();
567 567
     }
568 568
 
569 569
     /**
@@ -644,7 +644,7 @@  discard block
 block discarded – undo
644 644
      */
645 645
     public function getForeignKey()
646 646
     {
647
-        return snake_case(class_basename($this->getClass())) . '_id';
647
+        return snake_case(class_basename($this->getClass())).'_id';
648 648
     }
649 649
 
650 650
     /**
@@ -667,7 +667,7 @@  discard block
 block discarded – undo
667 667
 
668 668
         $localKey = $localKey ?: $this->getKeyName();
669 669
 
670
-        return new HasOne($relatedMapper, $entity, $relatedMap->getTable() . '.' . $foreignKey, $localKey);
670
+        return new HasOne($relatedMapper, $entity, $relatedMap->getTable().'.'.$foreignKey, $localKey);
671 671
     }
672 672
 
673 673
     /**
@@ -692,7 +692,7 @@  discard block
 block discarded – undo
692 692
 
693 693
         $table = $relatedMapper->getEntityMap()->getTable();
694 694
         
695
-        return new MorphOne($relatedMapper, $entity, $table . '.' . $type, $table . '.' . $id, $localKey);
695
+        return new MorphOne($relatedMapper, $entity, $table.'.'.$type, $table.'.'.$id, $localKey);
696 696
     }
697 697
 
698 698
     /**
@@ -721,7 +721,7 @@  discard block
 block discarded – undo
721 721
         // foreign key name by using the name of the relationship function, which
722 722
         // when combined with an "_id" should conventionally match the columns.
723 723
         if (is_null($foreignKey)) {
724
-            $foreignKey = snake_case($relation) . '_id';
724
+            $foreignKey = snake_case($relation).'_id';
725 725
         }
726 726
 
727 727
         $relatedMapper = $this->manager->mapper($related);
@@ -798,7 +798,7 @@  discard block
 block discarded – undo
798 798
 
799 799
         $relatedMapper = $this->manager->mapper($related);
800 800
 
801
-        $table = $relatedMapper->getEntityMap()->getTable() . '.' . $foreignKey;
801
+        $table = $relatedMapper->getEntityMap()->getTable().'.'.$foreignKey;
802 802
 
803 803
         $localKey = $localKey ?: $this->getKeyName();
804 804
 
@@ -856,7 +856,7 @@  discard block
 block discarded – undo
856 856
 
857 857
         $localKey = $localKey ?: $this->getKeyName();
858 858
         
859
-        return new MorphMany($relatedMapper, $entity, $table . '.' . $type, $table . '.' . $id, $localKey);
859
+        return new MorphMany($relatedMapper, $entity, $table.'.'.$type, $table.'.'.$id, $localKey);
860 860
     }
861 861
 
862 862
     /**
@@ -921,7 +921,7 @@  discard block
 block discarded – undo
921 921
         // First, we will need to determine the foreign key and "other key" for the
922 922
         // relationship. Once we have determined the keys we will make the query
923 923
         // instances, as well as the relationship instances we need for these.
924
-        $foreignKey = $foreignKey ?: $name . '_id';
924
+        $foreignKey = $foreignKey ?: $name.'_id';
925 925
 
926 926
         $relatedMapper = $this->manager->mapper($related);
927 927
 
@@ -951,7 +951,7 @@  discard block
 block discarded – undo
951 951
         // For the inverse of the polymorphic many-to-many relations, we will change
952 952
         // the way we determine the foreign and other keys, as it is the opposite
953 953
         // of the morph-to-many method since we're figuring out these inverses.
954
-        $otherKey = $otherKey ?: $name . '_id';
954
+        $otherKey = $otherKey ?: $name.'_id';
955 955
 
956 956
         return $this->morphToMany($entity, $related, $name, $table, $foreignKey, $otherKey, true);
957 957
     }
@@ -965,7 +965,7 @@  discard block
 block discarded – undo
965 965
     {
966 966
         $self = __FUNCTION__;
967 967
 
968
-        $caller = array_first(debug_backtrace(false), function ($key, $trace) use ($self) {
968
+        $caller = array_first(debug_backtrace(false), function($key, $trace) use ($self) {
969 969
             $caller = $trace['function'];
970 970
 
971 971
             return (!in_array($caller, EntityMap::$manyMethods) && $caller != $self);
@@ -1009,9 +1009,9 @@  discard block
 block discarded – undo
1009 1009
      */
1010 1010
     protected function getMorphs($name, $type, $id)
1011 1011
     {
1012
-        $type = $type ?: $name . '_type';
1012
+        $type = $type ?: $name.'_type';
1013 1013
 
1014
-        $id = $id ?: $name . '_id';
1014
+        $id = $id ?: $name.'_id';
1015 1015
 
1016 1016
         return [$type, $id];
1017 1017
     }
@@ -1176,7 +1176,7 @@  discard block
 block discarded – undo
1176 1176
     public function __call($method, $parameters)
1177 1177
     {
1178 1178
         if (!array_key_exists($method, $this->dynamicRelationships)) {
1179
-            throw new Exception(get_class($this) . " has no method $method");
1179
+            throw new Exception(get_class($this)." has no method $method");
1180 1180
         }
1181 1181
 
1182 1182
         // Add $this to parameters so the closure can call relationship method on the map.
Please login to merge, or discard this patch.
Indentation   +1239 added lines, -1239 removed lines patch added patch discarded remove patch
@@ -23,1243 +23,1243 @@
 block discarded – undo
23 23
  */
24 24
 class EntityMap
25 25
 {
26
-    /**
27
-     * The mapping driver to use with this entity
28
-     *
29
-     * @var  string
30
-     */
31
-    protected $driver = 'illuminate';
32
-
33
-    /**
34
-     * The Database Connection name for the model.
35
-     *
36
-     * @var string
37
-     */
38
-    protected $connection;
39
-
40
-    /**
41
-     * The table associated with the entity.
42
-     *
43
-     * @var string|null
44
-     */
45
-    protected $table = null;
46
-
47
-    /**
48
-     * The primary key for the model.
49
-     *
50
-     * @var string
51
-     */
52
-    protected $primaryKey = 'id';
53
-
54
-    /**
55
-     * Name of the entity's property that should
56
-     * contain the attributes, when $mapToProperties is false
57
-     * 
58
-     * @var string
59
-     */
60
-    protected $arrayName = 'attributes';
61
-
62
-    /**
63
-     * Array containing a list of class attributes. Mandatory if the
64
-     * mapped entity is a Plain PHP Object.
65
-     *
66
-     * @var array
67
-     */
68
-    protected $attributes = [];
69
-
70
-    /**
71
-     * Indicate if the entity's attributes should be mapped to the object's
72
-     * properties. If set to false, attributes will be assigned to an array
73
-     * defined by the $arrayName property of the EntityMap
74
-     * 
75
-     * @var boolean
76
-     */
77
-    protected $mapToProperties = false;
78
-
79
-    /**
80
-     * The Custom Domain Class to use with this mapping
81
-     *
82
-     * @var string|null
83
-     */
84
-    protected $class = null;
85
-
86
-    /**
87
-     * Embedded Value Objects
88
-     * 
89
-     * @var array
90
-     */
91
-    protected $embeddables = [];
92
-
93
-    /**
94
-     * Determine the relationships method used on the entity.
95
-     * If not set, mapper will autodetect them
96
-     *
97
-     * @var array
98
-     */
99
-    private $relationships = [];
100
-
101
-    /**
102
-     * Relationships that should be treated as collection.
103
-     *
104
-     * @var array
105
-     */
106
-    private $manyRelations = [];
107
-
108
-    /**
109
-     * Relationships that should be treated as single entity.
110
-     *
111
-     * @var array
112
-     */
113
-    private $singleRelations = [];
114
-
115
-    /**
116
-     * Relationships for which the key is stored in the Entity itself
117
-     *
118
-     * @var array
119
-     */
120
-    private $localRelations = [];
121
-
122
-    /**
123
-     * Relationships for which the key is stored in the Related Entity
124
-     *
125
-     * @var array
126
-     */
127
-    private $foreignRelations = [];
128
-
129
-    /**
130
-     * Relationships which use a pivot record.
131
-     *
132
-     * @var array
133
-     */
134
-    private $pivotRelations = [];
135
-
136
-    /**
137
-     * Dynamic relationships
138
-     *
139
-     * @var array
140
-     */
141
-    private $dynamicRelationships = [];
142
-
143
-    /**
144
-     * The number of models to return for pagination.
145
-     *
146
-     * @var int
147
-     */
148
-    protected $perPage = 15;
149
-
150
-    /**
151
-     * The relations to eager load on every query.
152
-     *
153
-     * @var array
154
-     */
155
-    protected $with = [];
156
-
157
-    /**
158
-     * The class name to be used in polymorphic relations.
159
-     *
160
-     * @var string
161
-     */
162
-    protected $morphClass;
163
-
164
-    /**
165
-     * Sequence name, to be used with postgreSql
166
-     * defaults to %table_name%_id_seq
167
-     *
168
-     * @var string|null
169
-     */
170
-    protected $sequence = null;
171
-
172
-    /**
173
-     * Indicates if the entity should be timestamped.
174
-     *
175
-     * @var bool
176
-     */
177
-    public $timestamps = false;
178
-
179
-    /**
180
-     * The name of the "created at" column.
181
-     *
182
-     * @var string
183
-     */
184
-    protected $createdAtColumn = 'created_at';
185
-
186
-    /**
187
-     * The name of the "updated at" column.
188
-     *
189
-     * @var string
190
-     */
191
-    protected $updatedAtColumn = 'updated_at';
192
-
193
-    /**
194
-     * Indicates if the entity uses softdeletes
195
-     *
196
-     * @var boolean
197
-     */
198
-    public $softDeletes = false;
199
-
200
-    /**
201
-     * The name of the "deleted at" column.
202
-     *
203
-     * @var string
204
-     */
205
-    protected $deletedAtColumn = 'deleted_at';
206
-
207
-    /**
208
-     * The many to many relationship methods.
209
-     *
210
-     * @var array
211
-     */
212
-    protected static $manyMethods = ['belongsToMany', 'morphToMany', 'morphedByMany'];
213
-
214
-    /**
215
-     * The 'Many' relationships classes, which related Entity attribute should be
216
-     * an array/entityCollection
217
-     *
218
-     * @var array
219
-     */
220
-    protected static $manyClasses = ['BelongsToMany', 'HasMany', 'HasManyThrough', 'MorphMany', 'MorphToMany'];
221
-
222
-    /**
223
-     * The 'Single' relationships classes, which related Entity attribute should be
224
-     * another Entity.
225
-     *
226
-     * @var array
227
-     */
228
-    protected static $singleClasses = ['BelongsTo', 'HasOne', 'MorphOne', 'MorphTo'];
229
-
230
-    /**
231
-     * Relationships with a pivot record
232
-     *
233
-     * @var array
234
-     */
235
-    protected static $pivotClasses = ['BelongsToMany', 'MorphToMany'];
236
-
237
-    /**
238
-     * Relationships on which key is stored in the Entity itself
239
-     *
240
-     * @var array
241
-     */
242
-    protected static $localClasses = ['BelongsTo', 'MorphTo'];
243
-
244
-    /**
245
-     * Relationships on which key is stored in the related Entity record or in a pivot record
246
-     *
247
-     * @var array
248
-     */
249
-    protected static $foreignClasses = [
250
-        'BelongsToMany',
251
-        'HasMany',
252
-        'HasManyThrough',
253
-        'MorphMany',
254
-        'MorphToMany',
255
-        'HasOne',
256
-        'MorphOne',
257
-    ];
258
-
259
-    /**
260
-     * The date format to use with the current database connection
261
-     *
262
-     * @var string
263
-     */
264
-    protected $dateFormat;
265
-
266
-    /**
267
-     * Set this property to true if the entity should be instantiated
268
-     * using the IoC Container
269
-     * 
270
-     * @var boolean
271
-     */
272
-    protected $dependencyInjection = false;
273
-
274
-    /**
275
-     * Set the usage of inheritance, possible values are :
276
-     * "single_table"
277
-     * null
278
-     * 
279
-     * @var string | null
280
-     */
281
-    protected $inheritanceType = null;
282
-
283
-    /**
284
-     * Discriminator column name
285
-     * 
286
-     * @var string
287
-     */
288
-    protected $discriminatorColumn = "type";
289
-
290
-    /**
291
-     * Allow using a string to define which entity type should be instantiated.
292
-     * If not set, analogue will uses entity's FQDN
293
-     * 
294
-     * @var array
295
-     */
296
-    protected $discriminatorColumnMap = [];
297
-
298
-    /**
299
-     * Return Domain class attributes, useful when mapping to a Plain PHP Object
300
-     *
301
-     * @return array
302
-     */
303
-    public function getAttributes()
304
-    {
305
-        return $this->attributes;
306
-    }
307
-
308
-    /**
309
-     * Set the domain class attributes
310
-     *
311
-     * @param array $attributeNames
312
-     */
313
-    public function setAttributes(array $attributeNames)
314
-    {
315
-        $this->attributes = $attributeNames;
316
-    }
317
-
318
-    /**
319
-     * Get all the attribute names for the class, including relationships, embeddables and primary key.
320
-     *
321
-     * @return array
322
-     */
323
-    public function getCompiledAttributes()
324
-    {
325
-        $key = $this->getKeyName();
326
-
327
-        $embeddables = array_keys($this->getEmbeddables());
328
-
329
-        $relationships = $this->getRelationships();
330
-
331
-        $attributes = $this->getAttributes();
332
-
333
-        return array_merge([$key], $embeddables, $relationships, $attributes);
334
-    }
335
-
336
-    /**
337
-     * Set the date format to use with the current database connection
338
-     *
339
-     * @param string $format
340
-     */
341
-    public function setDateFormat($format)
342
-    {
343
-        $this->dateFormat = $format;
344
-    }
345
-
346
-    /**
347
-     * Get the date format to use with the current database connection
348
-     *
349
-     *  @return string
350
-     */
351
-    public function getDateFormat()
352
-    {
353
-        return $this->dateFormat;
354
-    }
355
-
356
-    /**
357
-     * Set the Driver for this mapping
358
-     *
359
-     * @param string $driver
360
-     */
361
-    public function setDriver($driver)
362
-    {
363
-        $this->driver = $driver;
364
-    }
365
-
366
-    /**
367
-     * Get the Driver for this mapping.
368
-     *
369
-     * @return string
370
-     */
371
-    public function getDriver()
372
-    {
373
-        return $this->driver;
374
-    }
375
-
376
-    /**
377
-     * Set the db connection to use on the table
378
-     *
379
-     * @param $connection
380
-     */
381
-    public function setConnection($connection)
382
-    {
383
-        $this->connection = $connection;
384
-    }
385
-
386
-    /**
387
-     * Get the Database connection the Entity is stored on.
388
-     *
389
-     * @return string
390
-     */
391
-    public function getConnection()
392
-    {
393
-        return $this->connection;
394
-    }
395
-
396
-    /**
397
-     * Get the table associated with the entity.
398
-     *
399
-     * @return string
400
-     */
401
-    public function getTable()
402
-    {
403
-        if (!is_null($this->table)) {
404
-            return $this->table;
405
-        }
406
-
407
-        return str_replace('\\', '', snake_case(str_plural(class_basename($this->getClass()))));
408
-    }
409
-
410
-    /**
411
-     * Set the database table name
412
-     *
413
-     * @param  string $table
414
-     */
415
-    public function setTable($table)
416
-    {
417
-        $this->table = $table;
418
-    }
419
-
420
-    /**
421
-     * Get the pgSql sequence name
422
-     *
423
-     * @return string
424
-     */
425
-    public function getSequence()
426
-    {
427
-        if (!is_null($this->sequence)) {
428
-            return $this->sequence;
429
-        } else {
430
-            return $this->getTable() . '_id_seq';
431
-        }
432
-    }
433
-
434
-    /**
435
-     * Get the custom entity class
436
-     *
437
-     * @return string namespaced class name
438
-     */
439
-    public function getClass()
440
-    {
441
-        return isset($this->class) ? $this->class : null;
442
-    }
443
-
444
-    /**
445
-     * Set the custom entity class
446
-     *
447
-     * @param string $class namespaced class name
448
-     */
449
-    public function setClass($class)
450
-    {
451
-        $this->class = $class;
452
-    }
453
-
454
-    /**
455
-     * Get the embedded Value Objects
456
-     *
457
-     * @return array
458
-     */
459
-    public function getEmbeddables()
460
-    {
461
-        return $this->embeddables;
462
-    }
463
-
464
-    /**
465
-     * Set the embedded Value Objects
466
-     *
467
-     * @param array $embeddables
468
-     */
469
-    public function setEmbeddables(array $embeddables)
470
-    {
471
-        $this->embeddables = $embeddables;
472
-    }
473
-
474
-    /**
475
-     * Get the relationships to map on a custom domain
476
-     * class.
477
-     *
478
-     * @return array
479
-     */
480
-    public function getRelationships()
481
-    {
482
-        return $this->relationships;
483
-    }
484
-
485
-    /**
486
-     * Relationships of the Entity type
487
-     *
488
-     * @return array
489
-     */
490
-    public function getSingleRelationships()
491
-    {
492
-        return $this->singleRelations;
493
-    }
494
-
495
-    /**
496
-     * Relationships of type Collection
497
-     *
498
-     * @return array
499
-     */
500
-    public function getManyRelationships()
501
-    {
502
-        return $this->manyRelations;
503
-    }
504
-
505
-    /**
506
-     * Relationships with foreign key in the mapped entity record.
507
-     *
508
-     * @return array
509
-     */
510
-    public function getLocalRelationships()
511
-    {
512
-        return $this->localRelations;
513
-    }
514
-
515
-    /**
516
-     * Relationships with foreign key in the related Entity record
517
-     *
518
-     * @return array
519
-     */
520
-    public function getForeignRelationships()
521
-    {
522
-        return $this->foreignRelations;
523
-    }
524
-
525
-    /**
526
-     * Relationships which keys are stored in a pivot record
527
-     *
528
-     * @return array
529
-     */
530
-    public function getPivotRelationships()
531
-    {
532
-        return $this->pivotRelations;
533
-    }
534
-
535
-    /**
536
-     * Add a Dynamic Relationship method at runtime. This has to be done
537
-     * by hooking the 'initializing' event, before entityMap is initialized.
538
-     *
539
-     * @param string  $name         Relation name
540
-     * @param \Closure $relationship
541
-     *
542
-     * @return void
543
-     */
544
-    public function addRelationshipMethod($name, \Closure $relationship)
545
-    {
546
-        $this->dynamicRelationships[$name] = $relationship;
547
-    }
548
-
549
-    /**
550
-     * Get the dynamic relationship method names.
551
-     *
552
-     * @return array
553
-     */
554
-    public function getDynamicRelationships()
555
-    {
556
-        return array_keys($this->dynamicRelationships);
557
-    }
558
-
559
-    /**
560
-     * Get the relationships that have to be eager loaded
561
-     * on each request.
562
-     *
563
-     * @return array
564
-     */
565
-    public function getEagerloadedRelationships()
566
-    {
567
-        return $this->with;
568
-    }
569
-
570
-    /**
571
-     * Get the primary key for the entity.
572
-     *
573
-     * @return string
574
-     */
575
-    public function getKeyName()
576
-    {
577
-        return $this->primaryKey;
578
-    }
579
-
580
-    /**
581
-     * Set the primary key for the entity.
582
-     *
583
-     * @param $key
584
-     * @return void
585
-     */
586
-    public function setKeyName($key)
587
-    {
588
-        $this->primaryKey = $key;
589
-    }
590
-
591
-    /**
592
-     * Get the table qualified key name.
593
-     *
594
-     * @return string
595
-     */
596
-    public function getQualifiedKeyName()
597
-    {
598
-        return $this->getTable() . '.' . $this->getKeyName();
599
-    }
600
-
601
-    /**
602
-     * Get the number of models to return per page.
603
-     *
604
-     * @return int
605
-     */
606
-    public function getPerPage()
607
-    {
608
-        return $this->perPage;
609
-    }
610
-
611
-    /**
612
-     * Set the number of models to return per page.
613
-     *
614
-     * @param  int $perPage
615
-     * @return void
616
-     */
617
-    public function setPerPage($perPage)
618
-    {
619
-        $this->perPage = $perPage;
620
-    }
621
-
622
-    /**
623
-     * Determine if the entity uses get.
624
-     *
625
-     * @return bool
626
-     */
627
-    public function usesTimestamps()
628
-    {
629
-        return $this->timestamps;
630
-    }
631
-
632
-    /**
633
-     * Determine if the entity uses soft deletes
634
-     *
635
-     * @return bool
636
-     */
637
-    public function usesSoftDeletes()
638
-    {
639
-        return $this->softDeletes;
640
-    }
641
-
642
-    /**
643
-     * Get the 'created_at' column name
644
-     *
645
-     * @return string
646
-     */
647
-    public function getCreatedAtColumn()
648
-    {
649
-        return $this->createdAtColumn;
650
-    }
651
-
652
-    /**
653
-     * Get the 'updated_at' column name
654
-     *
655
-     * @return string
656
-     */
657
-    public function getUpdatedAtColumn()
658
-    {
659
-        return $this->updatedAtColumn;
660
-    }
661
-
662
-    /**
663
-     * Get the deleted_at column
664
-     *
665
-     * @return string
666
-     */
667
-    public function getQualifiedDeletedAtColumn()
668
-    {
669
-        return $this->deletedAtColumn;
670
-    }
671
-
672
-    /**
673
-     * Get the default foreign key name for the model.
674
-     *
675
-     * @return string
676
-     */
677
-    public function getForeignKey()
678
-    {
679
-        return snake_case(class_basename($this->getClass())) . '_id';
680
-    }
681
-
682
-    /**
683
-     * Return the inheritance type used by the entity.
684
-     *
685
-     * @return string|null
686
-     */
687
-    public function getInheritanceType()
688
-    {
689
-        return $this->inheritanceType;
690
-    }
691
-
692
-    /**
693
-     * Return the discriminator column name on the entity that's
694
-     * used for table inheritance.
695
-     *
696
-     * @return string
697
-     */
698
-    public function getDiscriminatorColumn()
699
-    {
700
-        return $this->discriminatorColumn;
701
-    }
702
-
703
-    /**
704
-     * Return the mapping of discriminator column values to
705
-     * entity class names that are used for table inheritance.
706
-     *
707
-     * @return array
708
-     */
709
-    public function getDiscriminatorColumnMap()
710
-    {
711
-        return $this->discriminatorColumnMap;
712
-    }
713
-
714
-    /**
715
-     * Return true if the entity should be instanciated using
716
-     * the IoC Container
717
-     * 
718
-     * @return boolean
719
-     */
720
-    public function useDependencyInjection()
721
-    {
722
-        return $this->dependencyInjection;
723
-    }
724
-
725
-    /**
726
-     * Define a one-to-one relationship.
727
-     *
728
-     * @param         $entity
729
-     * @param  string $relatedClass entity class
730
-     * @param  string $foreignKey
731
-     * @param  string $localKey
732
-     * @throws MappingException
733
-     * @return \Analogue\ORM\Relationships\HasOne
734
-     */
735
-    public function hasOne($entity, $relatedClass, $foreignKey = null, $localKey = null)
736
-    {
737
-        $foreignKey = $foreignKey ?: $this->getForeignKey();
738
-
739
-        $relatedMapper = Manager::getInstance()->mapper($relatedClass);
740
-
741
-        $relatedMap = $relatedMapper->getEntityMap();
742
-
743
-        $localKey = $localKey ?: $this->getKeyName();
744
-
745
-        return new HasOne($relatedMapper, $entity, $relatedMap->getTable() . '.' . $foreignKey, $localKey);
746
-    }
747
-
748
-    /**
749
-     * Define a polymorphic one-to-one relationship.
750
-     *
751
-     * @param  mixed       $entity
752
-     * @param  string      $related
753
-     * @param  string      $name
754
-     * @param  string|null $type
755
-     * @param  string|null $id
756
-     * @param  string|null $localKey
757
-     * @throws MappingException
758
-     * @return \Analogue\ORM\Relationships\MorphOne
759
-     */
760
-    public function morphOne($entity, $related, $name, $type = null, $id = null, $localKey = null)
761
-    {
762
-        list($type, $id) = $this->getMorphs($name, $type, $id);
763
-
764
-        $localKey = $localKey ?: $this->getKeyName();
765
-
766
-        $relatedMapper = Manager::getInstance()->mapper($related);
767
-
768
-        $table = $relatedMapper->getEntityMap()->getTable();
769
-
770
-        return new MorphOne($relatedMapper, $entity, $table . '.' . $type, $table . '.' . $id, $localKey);
771
-    }
772
-
773
-    /**
774
-     * Define an inverse one-to-one or many relationship.
775
-     *
776
-     * @param  mixed       $entity
777
-     * @param  string      $related
778
-     * @param  string|null $foreignKey
779
-     * @param  string|null $otherKey
780
-     * @param  string|null $relation
781
-     * @throws MappingException
782
-     * @return \Analogue\ORM\Relationships\BelongsTo
783
-     */
784
-    public function belongsTo($entity, $related, $foreignKey = null, $otherKey = null, $relation = null)
785
-    {
786
-        // If no relation name was given, we will use this debug backtrace to extract
787
-        // the calling method's name and use that as the relationship name as most
788
-        // of the time this will be what we desire to use for the relationships.
789
-        if (is_null($relation)) {
790
-            list(, $caller) = debug_backtrace(false);
791
-
792
-            $relation = $caller['function'];
793
-        }
794
-
795
-        // If no foreign key was supplied, we can use a backtrace to guess the proper
796
-        // foreign key name by using the name of the relationship function, which
797
-        // when combined with an "_id" should conventionally match the columns.
798
-        if (is_null($foreignKey)) {
799
-            $foreignKey = snake_case($relation) . '_id';
800
-        }
801
-
802
-        $relatedMapper = Manager::getInstance()->mapper($related);
803
-
804
-        $otherKey = $otherKey ?: $relatedMapper->getEntityMap()->getKeyName();
805
-
806
-        return new BelongsTo($relatedMapper, $entity, $foreignKey, $otherKey, $relation);
807
-    }
808
-
809
-    /**
810
-     * Define a polymorphic, inverse one-to-one or many relationship.
811
-     *
812
-     * @param  mixed       $entity
813
-     * @param  string|null $name
814
-     * @param  string|null $type
815
-     * @param  string|null $id
816
-     * @throws MappingException
817
-     * @return \Analogue\ORM\Relationships\MorphTo
818
-     */
819
-    public function morphTo($entity, $name = null, $type = null, $id = null)
820
-    {
821
-        // If no name is provided, we will use the backtrace to get the function name
822
-        // since that is most likely the name of the polymorphic interface. We can
823
-        // use that to get both the class and foreign key that will be utilized.
824
-        if (is_null($name)) {
825
-            list(, $caller) = debug_backtrace(false);
826
-
827
-            $name = snake_case($caller['function']);
828
-        }
829
-
830
-        list($type, $id) = $this->getMorphs($name, $type, $id);
831
-
832
-        $mapper = Manager::getInstance()->mapper(get_class($entity));
833
-
834
-        // If the type value is null it is probably safe to assume we're eager loading
835
-        // the relationship. When that is the case we will pass in a dummy query as
836
-        // there are multiple types in the morph and we can't use single queries.
837
-        $factory = new Factory;
838
-        $wrapper = $factory->make($entity);
839
-
840
-        if (is_null($class = $wrapper->getEntityAttribute($type))) {
841
-            return new MorphTo(
842
-                $mapper, $entity, $id, null, $type, $name
843
-            );
844
-        }
845
-
846
-        // If we are not eager loading the relationship we will essentially treat this
847
-        // as a belongs-to style relationship since morph-to extends that class and
848
-        // we will pass in the appropriate values so that it behaves as expected.
849
-        else {
850
-            $class = Manager::getInstance()->getInverseMorphMap($class);
851
-            $relatedMapper = Manager::getInstance()->mapper($class);
852
-
853
-            $foreignKey = $relatedMapper->getEntityMap()->getKeyName();
854
-
855
-            return new MorphTo(
856
-                $relatedMapper, $entity, $id, $foreignKey, $type, $name
857
-            );
858
-        }
859
-    }
860
-
861
-    /**
862
-     * Define a one-to-many relationship.
863
-     *
864
-     * @param  mixed       $entity
865
-     * @param  string      $related
866
-     * @param  string|null $foreignKey
867
-     * @param  string|null $localKey
868
-     * @throws MappingException
869
-     * @return \Analogue\ORM\Relationships\HasMany
870
-     */
871
-    public function hasMany($entity, $related, $foreignKey = null, $localKey = null)
872
-    {
873
-        $foreignKey = $foreignKey ?: $this->getForeignKey();
874
-
875
-        $relatedMapper = Manager::getInstance()->mapper($related);
876
-
877
-        $table = $relatedMapper->getEntityMap()->getTable() . '.' . $foreignKey;
878
-
879
-        $localKey = $localKey ?: $this->getKeyName();
880
-
881
-        return new HasMany($relatedMapper, $entity, $table, $localKey);
882
-    }
883
-
884
-    /**
885
-     * Define a has-many-through relationship.
886
-     *
887
-     * @param  mixed       $entity
888
-     * @param  string      $related
889
-     * @param  string      $through
890
-     * @param  string|null $firstKey
891
-     * @param  string|null $secondKey
892
-     * @throws MappingException
893
-     * @return \Analogue\ORM\Relationships\HasManyThrough
894
-     */
895
-    public function hasManyThrough($entity, $related, $through, $firstKey = null, $secondKey = null)
896
-    {
897
-        $relatedMapper = Manager::getInstance()->mapper($related);
898
-
899
-        $throughMapper = Manager::getInstance()->mapper($through);
900
-
901
-
902
-        $firstKey = $firstKey ?: $this->getForeignKey();
903
-
904
-        $throughMap = $throughMapper->getEntityMap();
905
-
906
-        $secondKey = $secondKey ?: $throughMap->getForeignKey();
907
-
908
-        return new HasManyThrough($relatedMapper, $entity, $throughMap, $firstKey, $secondKey);
909
-    }
910
-
911
-    /**
912
-     * Define a polymorphic one-to-many relationship.
913
-     *
914
-     * @param  mixed       $entity
915
-     * @param  string      $related
916
-     * @param  string      $name
917
-     * @param  string|null $type
918
-     * @param  string|null $id
919
-     * @param  string|null $localKey
920
-     * @return \Analogue\ORM\Relationships\MorphMany
921
-     */
922
-    public function morphMany($entity, $related, $name, $type = null, $id = null, $localKey = null)
923
-    {
924
-        // Here we will gather up the morph type and ID for the relationship so that we
925
-        // can properly query the intermediate table of a relation. Finally, we will
926
-        // get the table and create the relationship instances for the developers.
927
-        list($type, $id) = $this->getMorphs($name, $type, $id);
928
-
929
-        $relatedMapper = Manager::getInstance()->mapper($related);
930
-
931
-        $table = $relatedMapper->getEntityMap()->getTable();
932
-
933
-        $localKey = $localKey ?: $this->getKeyName();
934
-
935
-        return new MorphMany($relatedMapper, $entity, $table . '.' . $type, $table . '.' . $id, $localKey);
936
-    }
937
-
938
-    /**
939
-     * Define a many-to-many relationship.
940
-     *
941
-     * @param  mixed       $entity
942
-     * @param  string      $related
943
-     * @param  string|null $table
944
-     * @param  string|null $foreignKey
945
-     * @param  string|null $otherKey
946
-     * @param  string|null $relation
947
-     * @throws MappingException
948
-     * @return \Analogue\ORM\Relationships\BelongsToMany
949
-     */
950
-    public function belongsToMany($entity, $related, $table = null, $foreignKey = null, $otherKey = null, $relation = null)
951
-    {
952
-        // If no relationship name was passed, we will pull backtraces to get the
953
-        // name of the calling function. We will use that function name as the
954
-        // title of this relation since that is a great convention to apply.
955
-        if (is_null($relation)) {
956
-            $relation = $this->getBelongsToManyCaller();
957
-        }
958
-
959
-        // First, we'll need to determine the foreign key and "other key" for the
960
-        // relationship. Once we have determined the keys we'll make the query
961
-        // instances as well as the relationship instances we need for this.
962
-        $foreignKey = $foreignKey ?: $this->getForeignKey();
963
-
964
-        $relatedMapper = Manager::getInstance()->mapper($related);
965
-
966
-        $relatedMap = $relatedMapper->getEntityMap();
967
-
968
-        $otherKey = $otherKey ?: $relatedMap->getForeignKey();
969
-
970
-        // If no table name was provided, we can guess it by concatenating the two
971
-        // models using underscores in alphabetical order. The two model names
972
-        // are transformed to snake case from their default CamelCase also.
973
-        if (is_null($table)) {
974
-            $table = $this->joiningTable($relatedMap);
975
-        }
976
-
977
-        return new BelongsToMany($relatedMapper, $entity, $table, $foreignKey, $otherKey, $relation);
978
-    }
979
-
980
-    /**
981
-     * Define a polymorphic many-to-many relationship.
982
-     *
983
-     * @param  mixed       $entity
984
-     * @param  string      $related
985
-     * @param  string      $name
986
-     * @param  string|null $table
987
-     * @param  string|null $foreignKey
988
-     * @param  string|null $otherKey
989
-     * @param  bool        $inverse
990
-     * @throws MappingException
991
-     * @return \Analogue\ORM\Relationships\MorphToMany
992
-     */
993
-    public function morphToMany($entity, $related, $name, $table = null, $foreignKey = null, $otherKey = null, $inverse = false)
994
-    {
995
-        $caller = $this->getBelongsToManyCaller();
996
-
997
-        // First, we will need to determine the foreign key and "other key" for the
998
-        // relationship. Once we have determined the keys we will make the query
999
-        // instances, as well as the relationship instances we need for these.
1000
-        $foreignKey = $foreignKey ?: $name . '_id';
1001
-
1002
-        $relatedMapper = Manager::getInstance()->mapper($related);
1003
-
1004
-        $otherKey = $otherKey ?: $relatedMapper->getEntityMap()->getForeignKey();
1005
-
1006
-        $table = $table ?: str_plural($name);
1007
-
1008
-        return new MorphToMany($relatedMapper, $entity, $name, $table, $foreignKey, $otherKey, $caller, $inverse);
1009
-    }
1010
-
1011
-    /**
1012
-     * Define a polymorphic, inverse many-to-many relationship.
1013
-     *
1014
-     * @param  mixed       $entity
1015
-     * @param  string      $related
1016
-     * @param  string      $name
1017
-     * @param  string|null $table
1018
-     * @param  string|null $foreignKey
1019
-     * @param  string|null $otherKey
1020
-     * @throws MappingException
1021
-     * @return \Analogue\ORM\Relationships\MorphToMany
1022
-     */
1023
-    public function morphedByMany($entity, $related, $name, $table = null, $foreignKey = null, $otherKey = null)
1024
-    {
1025
-        $foreignKey = $foreignKey ?: $this->getForeignKey();
1026
-
1027
-        // For the inverse of the polymorphic many-to-many relations, we will change
1028
-        // the way we determine the foreign and other keys, as it is the opposite
1029
-        // of the morph-to-many method since we're figuring out these inverses.
1030
-        $otherKey = $otherKey ?: $name . '_id';
1031
-
1032
-        return $this->morphToMany($entity, $related, $name, $table, $foreignKey, $otherKey, true);
1033
-    }
1034
-
1035
-    /**
1036
-     * Get the relationship name of the belongs to many.
1037
-     *
1038
-     * @return string
1039
-     */
1040
-    protected function getBelongsToManyCaller()
1041
-    {
1042
-        $self = __FUNCTION__;
1043
-
1044
-        $caller = array_first(debug_backtrace(false), function ($key, $trace) use ($self) {
1045
-            $caller = $trace['function'];
1046
-
1047
-            return (!in_array($caller, EntityMap::$manyMethods) && $caller != $self);
1048
-        });
1049
-
1050
-        return !is_null($caller) ? $caller['function'] : null;
1051
-    }
1052
-
1053
-    /**
1054
-     * Get the joining table name for a many-to-many relation.
1055
-     *
1056
-     * @param  EntityMap $relatedMap
1057
-     * @return string
1058
-     */
1059
-    public function joiningTable($relatedMap)
1060
-    {
1061
-        // The joining table name, by convention, is simply the snake cased models
1062
-        // sorted alphabetically and concatenated with an underscore, so we can
1063
-        // just sort the models and join them together to get the table name.
1064
-        $base = $this->getTable();
1065
-
1066
-        $related = $relatedMap->getTable();
1067
-
1068
-        $tables = [$related, $base];
1069
-
1070
-        // Now that we have the model names in an array we can just sort them and
1071
-        // use the implode function to join them together with an underscores,
1072
-        // which is typically used by convention within the database system.
1073
-        sort($tables);
1074
-
1075
-        return strtolower(implode('_', $tables));
1076
-    }
1077
-
1078
-    /**
1079
-     * Get the polymorphic relationship columns.
1080
-     *
1081
-     * @param  string $name
1082
-     * @param  string $type
1083
-     * @param  string $id
1084
-     * @return string[]
1085
-     */
1086
-    protected function getMorphs($name, $type, $id)
1087
-    {
1088
-        $type = $type ?: $name . '_type';
1089
-
1090
-        $id = $id ?: $name . '_id';
1091
-
1092
-        return [$type, $id];
1093
-    }
1094
-
1095
-    /**
1096
-     * Get the class name for polymorphic relations.
1097
-     *
1098
-     * @return string
1099
-     */
1100
-    public function getMorphClass()
1101
-    {
1102
-        $morphClass = Manager::getInstance()->getMorphMap($this->getClass());
1103
-        return $this->morphClass ?: $morphClass;
1104
-    }
1105
-
1106
-    /**
1107
-     * Create a new Entity Collection instance.
1108
-     *
1109
-     * @param  array $entities
1110
-     * @return \Analogue\ORM\EntityCollection
1111
-     */
1112
-    public function newCollection(array $entities = [])
1113
-    {
1114
-        $collection = new EntityCollection($entities, $this);
1115
-        return $collection->keyBy($this->getKeyName());
1116
-    }
1117
-
1118
-    /**
1119
-     * Process EntityMap parsing at initialization time
1120
-     *
1121
-     * @return void
1122
-     */
1123
-    public function initialize()
1124
-    {
1125
-        $userMethods = $this->getCustomMethods();
1126
-
1127
-        // Parse EntityMap for method based relationship
1128
-        if (count($userMethods) > 0) {
1129
-            $this->relationships = $this->parseMethodsForRelationship($userMethods);
1130
-        }
1131
-
1132
-        // Parse EntityMap for dynamic relationships
1133
-        if (count($this->dynamicRelationships) > 0) {
1134
-            $this->relationships = $this->relationships + $this->getDynamicRelationships();
1135
-        }
1136
-    }
1137
-
1138
-    /**
1139
-     * Parse every relationships on the EntityMap and sort
1140
-     * them by type.
1141
-     *
1142
-     * @return void
1143
-     */
1144
-    public function boot()
1145
-    {
1146
-        if (count($this->relationships > 0)) {
1147
-            $this->sortRelationshipsByType();
1148
-        }
1149
-    }
1150
-
1151
-    /**
1152
-     * Get Methods that has been added in the child class.
1153
-     *
1154
-     * @return array
1155
-     */
1156
-    protected function getCustomMethods()
1157
-    {
1158
-        $mapMethods = get_class_methods($this);
1159
-
1160
-        $parentsMethods = get_class_methods('Analogue\ORM\EntityMap');
1161
-
1162
-        return array_diff($mapMethods, $parentsMethods);
1163
-    }
1164
-
1165
-    /**
1166
-     * Parse user's class methods for relationships
1167
-     *
1168
-     * @param  array $customMethods
1169
-     * @return array
1170
-     */
1171
-    protected function parseMethodsForRelationship(array $customMethods)
1172
-    {
1173
-        $relationships = [];
1174
-
1175
-        $class = new ReflectionClass(get_class($this));
1176
-
1177
-        // Get the mapped Entity class, as we will detect relationships
1178
-        // methods by testing that the first argument is type-hinted to
1179
-        // the same class as the mapped Entity.
1180
-        $entityClass = $this->getClass();
1181
-
1182
-        foreach ($customMethods as $methodName) {
1183
-            $method = $class->getMethod($methodName);
1184
-
1185
-            if ($method->getNumberOfParameters() > 0) {
1186
-                $params = $method->getParameters();
1187
-
1188
-                if ($params[0]->getClass() && ($params[0]->getClass()->name == $entityClass || is_subclass_of($entityClass, $params[0]->getClass()->name))) {
1189
-                    $relationships[] = $methodName;
1190
-                }
1191
-            }
1192
-        }
1193
-
1194
-        return $relationships;
1195
-    }
1196
-
1197
-    /**
1198
-     * Sort Relationships methods by type
1199
-     *
1200
-     * @return void
1201
-     */
1202
-    protected function sortRelationshipsByType()
1203
-    {
1204
-        $entityClass = $this->getClass();
1205
-
1206
-        // Instantiate a dummy entity which we will pass to relationship methods.
1207
-        $entity = unserialize(sprintf('O:%d:"%s":0:{}', strlen($entityClass), $entityClass));
1208
-
1209
-        foreach ($this->relationships as $relation) {
1210
-            $relationObject = $this->$relation($entity);
1211
-
1212
-            $class = class_basename(get_class($relationObject));
1213
-
1214
-            if (in_array($class, static::$singleClasses)) {
1215
-                $this->singleRelations[] = $relation;
1216
-            }
1217
-
1218
-            if (in_array($class, static::$manyClasses)) {
1219
-                $this->manyRelations[] = $relation;
1220
-            }
1221
-
1222
-            if (in_array($class, static::$localClasses)) {
1223
-                $this->localRelations[] = $relation;
1224
-            }
1225
-
1226
-            if (in_array($class, static::$foreignClasses)) {
1227
-                $this->foreignRelations[] = $relation;
1228
-            }
1229
-
1230
-            if (in_array($class, static::$pivotClasses)) {
1231
-                $this->pivotRelations[] = $relation;
1232
-            }
1233
-        }
1234
-    }
1235
-
1236
-    /**
1237
-     * Override this method for custom entity instantiation
1238
-     *
1239
-     * @return null
1240
-     */
1241
-    public function activator()
1242
-    {
1243
-        return null;
1244
-    }
1245
-
1246
-    /**
1247
-     * Call dynamic relationship, if it exists
1248
-     *
1249
-     * @param  string $method
1250
-     * @param  array  $parameters
1251
-     * @throws Exception
1252
-     * @return mixed
1253
-     */
1254
-    public function __call($method, $parameters)
1255
-    {
1256
-        if (!array_key_exists($method, $this->dynamicRelationships)) {
1257
-            throw new Exception(get_class($this) . " has no method $method");
1258
-        }
1259
-
1260
-        // Add $this to parameters so the closure can call relationship method on the map.
1261
-        $parameters[] = $this;
1262
-
1263
-        return  call_user_func_array([$this->dynamicRelationships[$method], $parameters]);
1264
-    }
26
+	/**
27
+	 * The mapping driver to use with this entity
28
+	 *
29
+	 * @var  string
30
+	 */
31
+	protected $driver = 'illuminate';
32
+
33
+	/**
34
+	 * The Database Connection name for the model.
35
+	 *
36
+	 * @var string
37
+	 */
38
+	protected $connection;
39
+
40
+	/**
41
+	 * The table associated with the entity.
42
+	 *
43
+	 * @var string|null
44
+	 */
45
+	protected $table = null;
46
+
47
+	/**
48
+	 * The primary key for the model.
49
+	 *
50
+	 * @var string
51
+	 */
52
+	protected $primaryKey = 'id';
53
+
54
+	/**
55
+	 * Name of the entity's property that should
56
+	 * contain the attributes, when $mapToProperties is false
57
+	 * 
58
+	 * @var string
59
+	 */
60
+	protected $arrayName = 'attributes';
61
+
62
+	/**
63
+	 * Array containing a list of class attributes. Mandatory if the
64
+	 * mapped entity is a Plain PHP Object.
65
+	 *
66
+	 * @var array
67
+	 */
68
+	protected $attributes = [];
69
+
70
+	/**
71
+	 * Indicate if the entity's attributes should be mapped to the object's
72
+	 * properties. If set to false, attributes will be assigned to an array
73
+	 * defined by the $arrayName property of the EntityMap
74
+	 * 
75
+	 * @var boolean
76
+	 */
77
+	protected $mapToProperties = false;
78
+
79
+	/**
80
+	 * The Custom Domain Class to use with this mapping
81
+	 *
82
+	 * @var string|null
83
+	 */
84
+	protected $class = null;
85
+
86
+	/**
87
+	 * Embedded Value Objects
88
+	 * 
89
+	 * @var array
90
+	 */
91
+	protected $embeddables = [];
92
+
93
+	/**
94
+	 * Determine the relationships method used on the entity.
95
+	 * If not set, mapper will autodetect them
96
+	 *
97
+	 * @var array
98
+	 */
99
+	private $relationships = [];
100
+
101
+	/**
102
+	 * Relationships that should be treated as collection.
103
+	 *
104
+	 * @var array
105
+	 */
106
+	private $manyRelations = [];
107
+
108
+	/**
109
+	 * Relationships that should be treated as single entity.
110
+	 *
111
+	 * @var array
112
+	 */
113
+	private $singleRelations = [];
114
+
115
+	/**
116
+	 * Relationships for which the key is stored in the Entity itself
117
+	 *
118
+	 * @var array
119
+	 */
120
+	private $localRelations = [];
121
+
122
+	/**
123
+	 * Relationships for which the key is stored in the Related Entity
124
+	 *
125
+	 * @var array
126
+	 */
127
+	private $foreignRelations = [];
128
+
129
+	/**
130
+	 * Relationships which use a pivot record.
131
+	 *
132
+	 * @var array
133
+	 */
134
+	private $pivotRelations = [];
135
+
136
+	/**
137
+	 * Dynamic relationships
138
+	 *
139
+	 * @var array
140
+	 */
141
+	private $dynamicRelationships = [];
142
+
143
+	/**
144
+	 * The number of models to return for pagination.
145
+	 *
146
+	 * @var int
147
+	 */
148
+	protected $perPage = 15;
149
+
150
+	/**
151
+	 * The relations to eager load on every query.
152
+	 *
153
+	 * @var array
154
+	 */
155
+	protected $with = [];
156
+
157
+	/**
158
+	 * The class name to be used in polymorphic relations.
159
+	 *
160
+	 * @var string
161
+	 */
162
+	protected $morphClass;
163
+
164
+	/**
165
+	 * Sequence name, to be used with postgreSql
166
+	 * defaults to %table_name%_id_seq
167
+	 *
168
+	 * @var string|null
169
+	 */
170
+	protected $sequence = null;
171
+
172
+	/**
173
+	 * Indicates if the entity should be timestamped.
174
+	 *
175
+	 * @var bool
176
+	 */
177
+	public $timestamps = false;
178
+
179
+	/**
180
+	 * The name of the "created at" column.
181
+	 *
182
+	 * @var string
183
+	 */
184
+	protected $createdAtColumn = 'created_at';
185
+
186
+	/**
187
+	 * The name of the "updated at" column.
188
+	 *
189
+	 * @var string
190
+	 */
191
+	protected $updatedAtColumn = 'updated_at';
192
+
193
+	/**
194
+	 * Indicates if the entity uses softdeletes
195
+	 *
196
+	 * @var boolean
197
+	 */
198
+	public $softDeletes = false;
199
+
200
+	/**
201
+	 * The name of the "deleted at" column.
202
+	 *
203
+	 * @var string
204
+	 */
205
+	protected $deletedAtColumn = 'deleted_at';
206
+
207
+	/**
208
+	 * The many to many relationship methods.
209
+	 *
210
+	 * @var array
211
+	 */
212
+	protected static $manyMethods = ['belongsToMany', 'morphToMany', 'morphedByMany'];
213
+
214
+	/**
215
+	 * The 'Many' relationships classes, which related Entity attribute should be
216
+	 * an array/entityCollection
217
+	 *
218
+	 * @var array
219
+	 */
220
+	protected static $manyClasses = ['BelongsToMany', 'HasMany', 'HasManyThrough', 'MorphMany', 'MorphToMany'];
221
+
222
+	/**
223
+	 * The 'Single' relationships classes, which related Entity attribute should be
224
+	 * another Entity.
225
+	 *
226
+	 * @var array
227
+	 */
228
+	protected static $singleClasses = ['BelongsTo', 'HasOne', 'MorphOne', 'MorphTo'];
229
+
230
+	/**
231
+	 * Relationships with a pivot record
232
+	 *
233
+	 * @var array
234
+	 */
235
+	protected static $pivotClasses = ['BelongsToMany', 'MorphToMany'];
236
+
237
+	/**
238
+	 * Relationships on which key is stored in the Entity itself
239
+	 *
240
+	 * @var array
241
+	 */
242
+	protected static $localClasses = ['BelongsTo', 'MorphTo'];
243
+
244
+	/**
245
+	 * Relationships on which key is stored in the related Entity record or in a pivot record
246
+	 *
247
+	 * @var array
248
+	 */
249
+	protected static $foreignClasses = [
250
+		'BelongsToMany',
251
+		'HasMany',
252
+		'HasManyThrough',
253
+		'MorphMany',
254
+		'MorphToMany',
255
+		'HasOne',
256
+		'MorphOne',
257
+	];
258
+
259
+	/**
260
+	 * The date format to use with the current database connection
261
+	 *
262
+	 * @var string
263
+	 */
264
+	protected $dateFormat;
265
+
266
+	/**
267
+	 * Set this property to true if the entity should be instantiated
268
+	 * using the IoC Container
269
+	 * 
270
+	 * @var boolean
271
+	 */
272
+	protected $dependencyInjection = false;
273
+
274
+	/**
275
+	 * Set the usage of inheritance, possible values are :
276
+	 * "single_table"
277
+	 * null
278
+	 * 
279
+	 * @var string | null
280
+	 */
281
+	protected $inheritanceType = null;
282
+
283
+	/**
284
+	 * Discriminator column name
285
+	 * 
286
+	 * @var string
287
+	 */
288
+	protected $discriminatorColumn = "type";
289
+
290
+	/**
291
+	 * Allow using a string to define which entity type should be instantiated.
292
+	 * If not set, analogue will uses entity's FQDN
293
+	 * 
294
+	 * @var array
295
+	 */
296
+	protected $discriminatorColumnMap = [];
297
+
298
+	/**
299
+	 * Return Domain class attributes, useful when mapping to a Plain PHP Object
300
+	 *
301
+	 * @return array
302
+	 */
303
+	public function getAttributes()
304
+	{
305
+		return $this->attributes;
306
+	}
307
+
308
+	/**
309
+	 * Set the domain class attributes
310
+	 *
311
+	 * @param array $attributeNames
312
+	 */
313
+	public function setAttributes(array $attributeNames)
314
+	{
315
+		$this->attributes = $attributeNames;
316
+	}
317
+
318
+	/**
319
+	 * Get all the attribute names for the class, including relationships, embeddables and primary key.
320
+	 *
321
+	 * @return array
322
+	 */
323
+	public function getCompiledAttributes()
324
+	{
325
+		$key = $this->getKeyName();
326
+
327
+		$embeddables = array_keys($this->getEmbeddables());
328
+
329
+		$relationships = $this->getRelationships();
330
+
331
+		$attributes = $this->getAttributes();
332
+
333
+		return array_merge([$key], $embeddables, $relationships, $attributes);
334
+	}
335
+
336
+	/**
337
+	 * Set the date format to use with the current database connection
338
+	 *
339
+	 * @param string $format
340
+	 */
341
+	public function setDateFormat($format)
342
+	{
343
+		$this->dateFormat = $format;
344
+	}
345
+
346
+	/**
347
+	 * Get the date format to use with the current database connection
348
+	 *
349
+	 *  @return string
350
+	 */
351
+	public function getDateFormat()
352
+	{
353
+		return $this->dateFormat;
354
+	}
355
+
356
+	/**
357
+	 * Set the Driver for this mapping
358
+	 *
359
+	 * @param string $driver
360
+	 */
361
+	public function setDriver($driver)
362
+	{
363
+		$this->driver = $driver;
364
+	}
365
+
366
+	/**
367
+	 * Get the Driver for this mapping.
368
+	 *
369
+	 * @return string
370
+	 */
371
+	public function getDriver()
372
+	{
373
+		return $this->driver;
374
+	}
375
+
376
+	/**
377
+	 * Set the db connection to use on the table
378
+	 *
379
+	 * @param $connection
380
+	 */
381
+	public function setConnection($connection)
382
+	{
383
+		$this->connection = $connection;
384
+	}
385
+
386
+	/**
387
+	 * Get the Database connection the Entity is stored on.
388
+	 *
389
+	 * @return string
390
+	 */
391
+	public function getConnection()
392
+	{
393
+		return $this->connection;
394
+	}
395
+
396
+	/**
397
+	 * Get the table associated with the entity.
398
+	 *
399
+	 * @return string
400
+	 */
401
+	public function getTable()
402
+	{
403
+		if (!is_null($this->table)) {
404
+			return $this->table;
405
+		}
406
+
407
+		return str_replace('\\', '', snake_case(str_plural(class_basename($this->getClass()))));
408
+	}
409
+
410
+	/**
411
+	 * Set the database table name
412
+	 *
413
+	 * @param  string $table
414
+	 */
415
+	public function setTable($table)
416
+	{
417
+		$this->table = $table;
418
+	}
419
+
420
+	/**
421
+	 * Get the pgSql sequence name
422
+	 *
423
+	 * @return string
424
+	 */
425
+	public function getSequence()
426
+	{
427
+		if (!is_null($this->sequence)) {
428
+			return $this->sequence;
429
+		} else {
430
+			return $this->getTable() . '_id_seq';
431
+		}
432
+	}
433
+
434
+	/**
435
+	 * Get the custom entity class
436
+	 *
437
+	 * @return string namespaced class name
438
+	 */
439
+	public function getClass()
440
+	{
441
+		return isset($this->class) ? $this->class : null;
442
+	}
443
+
444
+	/**
445
+	 * Set the custom entity class
446
+	 *
447
+	 * @param string $class namespaced class name
448
+	 */
449
+	public function setClass($class)
450
+	{
451
+		$this->class = $class;
452
+	}
453
+
454
+	/**
455
+	 * Get the embedded Value Objects
456
+	 *
457
+	 * @return array
458
+	 */
459
+	public function getEmbeddables()
460
+	{
461
+		return $this->embeddables;
462
+	}
463
+
464
+	/**
465
+	 * Set the embedded Value Objects
466
+	 *
467
+	 * @param array $embeddables
468
+	 */
469
+	public function setEmbeddables(array $embeddables)
470
+	{
471
+		$this->embeddables = $embeddables;
472
+	}
473
+
474
+	/**
475
+	 * Get the relationships to map on a custom domain
476
+	 * class.
477
+	 *
478
+	 * @return array
479
+	 */
480
+	public function getRelationships()
481
+	{
482
+		return $this->relationships;
483
+	}
484
+
485
+	/**
486
+	 * Relationships of the Entity type
487
+	 *
488
+	 * @return array
489
+	 */
490
+	public function getSingleRelationships()
491
+	{
492
+		return $this->singleRelations;
493
+	}
494
+
495
+	/**
496
+	 * Relationships of type Collection
497
+	 *
498
+	 * @return array
499
+	 */
500
+	public function getManyRelationships()
501
+	{
502
+		return $this->manyRelations;
503
+	}
504
+
505
+	/**
506
+	 * Relationships with foreign key in the mapped entity record.
507
+	 *
508
+	 * @return array
509
+	 */
510
+	public function getLocalRelationships()
511
+	{
512
+		return $this->localRelations;
513
+	}
514
+
515
+	/**
516
+	 * Relationships with foreign key in the related Entity record
517
+	 *
518
+	 * @return array
519
+	 */
520
+	public function getForeignRelationships()
521
+	{
522
+		return $this->foreignRelations;
523
+	}
524
+
525
+	/**
526
+	 * Relationships which keys are stored in a pivot record
527
+	 *
528
+	 * @return array
529
+	 */
530
+	public function getPivotRelationships()
531
+	{
532
+		return $this->pivotRelations;
533
+	}
534
+
535
+	/**
536
+	 * Add a Dynamic Relationship method at runtime. This has to be done
537
+	 * by hooking the 'initializing' event, before entityMap is initialized.
538
+	 *
539
+	 * @param string  $name         Relation name
540
+	 * @param \Closure $relationship
541
+	 *
542
+	 * @return void
543
+	 */
544
+	public function addRelationshipMethod($name, \Closure $relationship)
545
+	{
546
+		$this->dynamicRelationships[$name] = $relationship;
547
+	}
548
+
549
+	/**
550
+	 * Get the dynamic relationship method names.
551
+	 *
552
+	 * @return array
553
+	 */
554
+	public function getDynamicRelationships()
555
+	{
556
+		return array_keys($this->dynamicRelationships);
557
+	}
558
+
559
+	/**
560
+	 * Get the relationships that have to be eager loaded
561
+	 * on each request.
562
+	 *
563
+	 * @return array
564
+	 */
565
+	public function getEagerloadedRelationships()
566
+	{
567
+		return $this->with;
568
+	}
569
+
570
+	/**
571
+	 * Get the primary key for the entity.
572
+	 *
573
+	 * @return string
574
+	 */
575
+	public function getKeyName()
576
+	{
577
+		return $this->primaryKey;
578
+	}
579
+
580
+	/**
581
+	 * Set the primary key for the entity.
582
+	 *
583
+	 * @param $key
584
+	 * @return void
585
+	 */
586
+	public function setKeyName($key)
587
+	{
588
+		$this->primaryKey = $key;
589
+	}
590
+
591
+	/**
592
+	 * Get the table qualified key name.
593
+	 *
594
+	 * @return string
595
+	 */
596
+	public function getQualifiedKeyName()
597
+	{
598
+		return $this->getTable() . '.' . $this->getKeyName();
599
+	}
600
+
601
+	/**
602
+	 * Get the number of models to return per page.
603
+	 *
604
+	 * @return int
605
+	 */
606
+	public function getPerPage()
607
+	{
608
+		return $this->perPage;
609
+	}
610
+
611
+	/**
612
+	 * Set the number of models to return per page.
613
+	 *
614
+	 * @param  int $perPage
615
+	 * @return void
616
+	 */
617
+	public function setPerPage($perPage)
618
+	{
619
+		$this->perPage = $perPage;
620
+	}
621
+
622
+	/**
623
+	 * Determine if the entity uses get.
624
+	 *
625
+	 * @return bool
626
+	 */
627
+	public function usesTimestamps()
628
+	{
629
+		return $this->timestamps;
630
+	}
631
+
632
+	/**
633
+	 * Determine if the entity uses soft deletes
634
+	 *
635
+	 * @return bool
636
+	 */
637
+	public function usesSoftDeletes()
638
+	{
639
+		return $this->softDeletes;
640
+	}
641
+
642
+	/**
643
+	 * Get the 'created_at' column name
644
+	 *
645
+	 * @return string
646
+	 */
647
+	public function getCreatedAtColumn()
648
+	{
649
+		return $this->createdAtColumn;
650
+	}
651
+
652
+	/**
653
+	 * Get the 'updated_at' column name
654
+	 *
655
+	 * @return string
656
+	 */
657
+	public function getUpdatedAtColumn()
658
+	{
659
+		return $this->updatedAtColumn;
660
+	}
661
+
662
+	/**
663
+	 * Get the deleted_at column
664
+	 *
665
+	 * @return string
666
+	 */
667
+	public function getQualifiedDeletedAtColumn()
668
+	{
669
+		return $this->deletedAtColumn;
670
+	}
671
+
672
+	/**
673
+	 * Get the default foreign key name for the model.
674
+	 *
675
+	 * @return string
676
+	 */
677
+	public function getForeignKey()
678
+	{
679
+		return snake_case(class_basename($this->getClass())) . '_id';
680
+	}
681
+
682
+	/**
683
+	 * Return the inheritance type used by the entity.
684
+	 *
685
+	 * @return string|null
686
+	 */
687
+	public function getInheritanceType()
688
+	{
689
+		return $this->inheritanceType;
690
+	}
691
+
692
+	/**
693
+	 * Return the discriminator column name on the entity that's
694
+	 * used for table inheritance.
695
+	 *
696
+	 * @return string
697
+	 */
698
+	public function getDiscriminatorColumn()
699
+	{
700
+		return $this->discriminatorColumn;
701
+	}
702
+
703
+	/**
704
+	 * Return the mapping of discriminator column values to
705
+	 * entity class names that are used for table inheritance.
706
+	 *
707
+	 * @return array
708
+	 */
709
+	public function getDiscriminatorColumnMap()
710
+	{
711
+		return $this->discriminatorColumnMap;
712
+	}
713
+
714
+	/**
715
+	 * Return true if the entity should be instanciated using
716
+	 * the IoC Container
717
+	 * 
718
+	 * @return boolean
719
+	 */
720
+	public function useDependencyInjection()
721
+	{
722
+		return $this->dependencyInjection;
723
+	}
724
+
725
+	/**
726
+	 * Define a one-to-one relationship.
727
+	 *
728
+	 * @param         $entity
729
+	 * @param  string $relatedClass entity class
730
+	 * @param  string $foreignKey
731
+	 * @param  string $localKey
732
+	 * @throws MappingException
733
+	 * @return \Analogue\ORM\Relationships\HasOne
734
+	 */
735
+	public function hasOne($entity, $relatedClass, $foreignKey = null, $localKey = null)
736
+	{
737
+		$foreignKey = $foreignKey ?: $this->getForeignKey();
738
+
739
+		$relatedMapper = Manager::getInstance()->mapper($relatedClass);
740
+
741
+		$relatedMap = $relatedMapper->getEntityMap();
742
+
743
+		$localKey = $localKey ?: $this->getKeyName();
744
+
745
+		return new HasOne($relatedMapper, $entity, $relatedMap->getTable() . '.' . $foreignKey, $localKey);
746
+	}
747
+
748
+	/**
749
+	 * Define a polymorphic one-to-one relationship.
750
+	 *
751
+	 * @param  mixed       $entity
752
+	 * @param  string      $related
753
+	 * @param  string      $name
754
+	 * @param  string|null $type
755
+	 * @param  string|null $id
756
+	 * @param  string|null $localKey
757
+	 * @throws MappingException
758
+	 * @return \Analogue\ORM\Relationships\MorphOne
759
+	 */
760
+	public function morphOne($entity, $related, $name, $type = null, $id = null, $localKey = null)
761
+	{
762
+		list($type, $id) = $this->getMorphs($name, $type, $id);
763
+
764
+		$localKey = $localKey ?: $this->getKeyName();
765
+
766
+		$relatedMapper = Manager::getInstance()->mapper($related);
767
+
768
+		$table = $relatedMapper->getEntityMap()->getTable();
769
+
770
+		return new MorphOne($relatedMapper, $entity, $table . '.' . $type, $table . '.' . $id, $localKey);
771
+	}
772
+
773
+	/**
774
+	 * Define an inverse one-to-one or many relationship.
775
+	 *
776
+	 * @param  mixed       $entity
777
+	 * @param  string      $related
778
+	 * @param  string|null $foreignKey
779
+	 * @param  string|null $otherKey
780
+	 * @param  string|null $relation
781
+	 * @throws MappingException
782
+	 * @return \Analogue\ORM\Relationships\BelongsTo
783
+	 */
784
+	public function belongsTo($entity, $related, $foreignKey = null, $otherKey = null, $relation = null)
785
+	{
786
+		// If no relation name was given, we will use this debug backtrace to extract
787
+		// the calling method's name and use that as the relationship name as most
788
+		// of the time this will be what we desire to use for the relationships.
789
+		if (is_null($relation)) {
790
+			list(, $caller) = debug_backtrace(false);
791
+
792
+			$relation = $caller['function'];
793
+		}
794
+
795
+		// If no foreign key was supplied, we can use a backtrace to guess the proper
796
+		// foreign key name by using the name of the relationship function, which
797
+		// when combined with an "_id" should conventionally match the columns.
798
+		if (is_null($foreignKey)) {
799
+			$foreignKey = snake_case($relation) . '_id';
800
+		}
801
+
802
+		$relatedMapper = Manager::getInstance()->mapper($related);
803
+
804
+		$otherKey = $otherKey ?: $relatedMapper->getEntityMap()->getKeyName();
805
+
806
+		return new BelongsTo($relatedMapper, $entity, $foreignKey, $otherKey, $relation);
807
+	}
808
+
809
+	/**
810
+	 * Define a polymorphic, inverse one-to-one or many relationship.
811
+	 *
812
+	 * @param  mixed       $entity
813
+	 * @param  string|null $name
814
+	 * @param  string|null $type
815
+	 * @param  string|null $id
816
+	 * @throws MappingException
817
+	 * @return \Analogue\ORM\Relationships\MorphTo
818
+	 */
819
+	public function morphTo($entity, $name = null, $type = null, $id = null)
820
+	{
821
+		// If no name is provided, we will use the backtrace to get the function name
822
+		// since that is most likely the name of the polymorphic interface. We can
823
+		// use that to get both the class and foreign key that will be utilized.
824
+		if (is_null($name)) {
825
+			list(, $caller) = debug_backtrace(false);
826
+
827
+			$name = snake_case($caller['function']);
828
+		}
829
+
830
+		list($type, $id) = $this->getMorphs($name, $type, $id);
831
+
832
+		$mapper = Manager::getInstance()->mapper(get_class($entity));
833
+
834
+		// If the type value is null it is probably safe to assume we're eager loading
835
+		// the relationship. When that is the case we will pass in a dummy query as
836
+		// there are multiple types in the morph and we can't use single queries.
837
+		$factory = new Factory;
838
+		$wrapper = $factory->make($entity);
839
+
840
+		if (is_null($class = $wrapper->getEntityAttribute($type))) {
841
+			return new MorphTo(
842
+				$mapper, $entity, $id, null, $type, $name
843
+			);
844
+		}
845
+
846
+		// If we are not eager loading the relationship we will essentially treat this
847
+		// as a belongs-to style relationship since morph-to extends that class and
848
+		// we will pass in the appropriate values so that it behaves as expected.
849
+		else {
850
+			$class = Manager::getInstance()->getInverseMorphMap($class);
851
+			$relatedMapper = Manager::getInstance()->mapper($class);
852
+
853
+			$foreignKey = $relatedMapper->getEntityMap()->getKeyName();
854
+
855
+			return new MorphTo(
856
+				$relatedMapper, $entity, $id, $foreignKey, $type, $name
857
+			);
858
+		}
859
+	}
860
+
861
+	/**
862
+	 * Define a one-to-many relationship.
863
+	 *
864
+	 * @param  mixed       $entity
865
+	 * @param  string      $related
866
+	 * @param  string|null $foreignKey
867
+	 * @param  string|null $localKey
868
+	 * @throws MappingException
869
+	 * @return \Analogue\ORM\Relationships\HasMany
870
+	 */
871
+	public function hasMany($entity, $related, $foreignKey = null, $localKey = null)
872
+	{
873
+		$foreignKey = $foreignKey ?: $this->getForeignKey();
874
+
875
+		$relatedMapper = Manager::getInstance()->mapper($related);
876
+
877
+		$table = $relatedMapper->getEntityMap()->getTable() . '.' . $foreignKey;
878
+
879
+		$localKey = $localKey ?: $this->getKeyName();
880
+
881
+		return new HasMany($relatedMapper, $entity, $table, $localKey);
882
+	}
883
+
884
+	/**
885
+	 * Define a has-many-through relationship.
886
+	 *
887
+	 * @param  mixed       $entity
888
+	 * @param  string      $related
889
+	 * @param  string      $through
890
+	 * @param  string|null $firstKey
891
+	 * @param  string|null $secondKey
892
+	 * @throws MappingException
893
+	 * @return \Analogue\ORM\Relationships\HasManyThrough
894
+	 */
895
+	public function hasManyThrough($entity, $related, $through, $firstKey = null, $secondKey = null)
896
+	{
897
+		$relatedMapper = Manager::getInstance()->mapper($related);
898
+
899
+		$throughMapper = Manager::getInstance()->mapper($through);
900
+
901
+
902
+		$firstKey = $firstKey ?: $this->getForeignKey();
903
+
904
+		$throughMap = $throughMapper->getEntityMap();
905
+
906
+		$secondKey = $secondKey ?: $throughMap->getForeignKey();
907
+
908
+		return new HasManyThrough($relatedMapper, $entity, $throughMap, $firstKey, $secondKey);
909
+	}
910
+
911
+	/**
912
+	 * Define a polymorphic one-to-many relationship.
913
+	 *
914
+	 * @param  mixed       $entity
915
+	 * @param  string      $related
916
+	 * @param  string      $name
917
+	 * @param  string|null $type
918
+	 * @param  string|null $id
919
+	 * @param  string|null $localKey
920
+	 * @return \Analogue\ORM\Relationships\MorphMany
921
+	 */
922
+	public function morphMany($entity, $related, $name, $type = null, $id = null, $localKey = null)
923
+	{
924
+		// Here we will gather up the morph type and ID for the relationship so that we
925
+		// can properly query the intermediate table of a relation. Finally, we will
926
+		// get the table and create the relationship instances for the developers.
927
+		list($type, $id) = $this->getMorphs($name, $type, $id);
928
+
929
+		$relatedMapper = Manager::getInstance()->mapper($related);
930
+
931
+		$table = $relatedMapper->getEntityMap()->getTable();
932
+
933
+		$localKey = $localKey ?: $this->getKeyName();
934
+
935
+		return new MorphMany($relatedMapper, $entity, $table . '.' . $type, $table . '.' . $id, $localKey);
936
+	}
937
+
938
+	/**
939
+	 * Define a many-to-many relationship.
940
+	 *
941
+	 * @param  mixed       $entity
942
+	 * @param  string      $related
943
+	 * @param  string|null $table
944
+	 * @param  string|null $foreignKey
945
+	 * @param  string|null $otherKey
946
+	 * @param  string|null $relation
947
+	 * @throws MappingException
948
+	 * @return \Analogue\ORM\Relationships\BelongsToMany
949
+	 */
950
+	public function belongsToMany($entity, $related, $table = null, $foreignKey = null, $otherKey = null, $relation = null)
951
+	{
952
+		// If no relationship name was passed, we will pull backtraces to get the
953
+		// name of the calling function. We will use that function name as the
954
+		// title of this relation since that is a great convention to apply.
955
+		if (is_null($relation)) {
956
+			$relation = $this->getBelongsToManyCaller();
957
+		}
958
+
959
+		// First, we'll need to determine the foreign key and "other key" for the
960
+		// relationship. Once we have determined the keys we'll make the query
961
+		// instances as well as the relationship instances we need for this.
962
+		$foreignKey = $foreignKey ?: $this->getForeignKey();
963
+
964
+		$relatedMapper = Manager::getInstance()->mapper($related);
965
+
966
+		$relatedMap = $relatedMapper->getEntityMap();
967
+
968
+		$otherKey = $otherKey ?: $relatedMap->getForeignKey();
969
+
970
+		// If no table name was provided, we can guess it by concatenating the two
971
+		// models using underscores in alphabetical order. The two model names
972
+		// are transformed to snake case from their default CamelCase also.
973
+		if (is_null($table)) {
974
+			$table = $this->joiningTable($relatedMap);
975
+		}
976
+
977
+		return new BelongsToMany($relatedMapper, $entity, $table, $foreignKey, $otherKey, $relation);
978
+	}
979
+
980
+	/**
981
+	 * Define a polymorphic many-to-many relationship.
982
+	 *
983
+	 * @param  mixed       $entity
984
+	 * @param  string      $related
985
+	 * @param  string      $name
986
+	 * @param  string|null $table
987
+	 * @param  string|null $foreignKey
988
+	 * @param  string|null $otherKey
989
+	 * @param  bool        $inverse
990
+	 * @throws MappingException
991
+	 * @return \Analogue\ORM\Relationships\MorphToMany
992
+	 */
993
+	public function morphToMany($entity, $related, $name, $table = null, $foreignKey = null, $otherKey = null, $inverse = false)
994
+	{
995
+		$caller = $this->getBelongsToManyCaller();
996
+
997
+		// First, we will need to determine the foreign key and "other key" for the
998
+		// relationship. Once we have determined the keys we will make the query
999
+		// instances, as well as the relationship instances we need for these.
1000
+		$foreignKey = $foreignKey ?: $name . '_id';
1001
+
1002
+		$relatedMapper = Manager::getInstance()->mapper($related);
1003
+
1004
+		$otherKey = $otherKey ?: $relatedMapper->getEntityMap()->getForeignKey();
1005
+
1006
+		$table = $table ?: str_plural($name);
1007
+
1008
+		return new MorphToMany($relatedMapper, $entity, $name, $table, $foreignKey, $otherKey, $caller, $inverse);
1009
+	}
1010
+
1011
+	/**
1012
+	 * Define a polymorphic, inverse many-to-many relationship.
1013
+	 *
1014
+	 * @param  mixed       $entity
1015
+	 * @param  string      $related
1016
+	 * @param  string      $name
1017
+	 * @param  string|null $table
1018
+	 * @param  string|null $foreignKey
1019
+	 * @param  string|null $otherKey
1020
+	 * @throws MappingException
1021
+	 * @return \Analogue\ORM\Relationships\MorphToMany
1022
+	 */
1023
+	public function morphedByMany($entity, $related, $name, $table = null, $foreignKey = null, $otherKey = null)
1024
+	{
1025
+		$foreignKey = $foreignKey ?: $this->getForeignKey();
1026
+
1027
+		// For the inverse of the polymorphic many-to-many relations, we will change
1028
+		// the way we determine the foreign and other keys, as it is the opposite
1029
+		// of the morph-to-many method since we're figuring out these inverses.
1030
+		$otherKey = $otherKey ?: $name . '_id';
1031
+
1032
+		return $this->morphToMany($entity, $related, $name, $table, $foreignKey, $otherKey, true);
1033
+	}
1034
+
1035
+	/**
1036
+	 * Get the relationship name of the belongs to many.
1037
+	 *
1038
+	 * @return string
1039
+	 */
1040
+	protected function getBelongsToManyCaller()
1041
+	{
1042
+		$self = __FUNCTION__;
1043
+
1044
+		$caller = array_first(debug_backtrace(false), function ($key, $trace) use ($self) {
1045
+			$caller = $trace['function'];
1046
+
1047
+			return (!in_array($caller, EntityMap::$manyMethods) && $caller != $self);
1048
+		});
1049
+
1050
+		return !is_null($caller) ? $caller['function'] : null;
1051
+	}
1052
+
1053
+	/**
1054
+	 * Get the joining table name for a many-to-many relation.
1055
+	 *
1056
+	 * @param  EntityMap $relatedMap
1057
+	 * @return string
1058
+	 */
1059
+	public function joiningTable($relatedMap)
1060
+	{
1061
+		// The joining table name, by convention, is simply the snake cased models
1062
+		// sorted alphabetically and concatenated with an underscore, so we can
1063
+		// just sort the models and join them together to get the table name.
1064
+		$base = $this->getTable();
1065
+
1066
+		$related = $relatedMap->getTable();
1067
+
1068
+		$tables = [$related, $base];
1069
+
1070
+		// Now that we have the model names in an array we can just sort them and
1071
+		// use the implode function to join them together with an underscores,
1072
+		// which is typically used by convention within the database system.
1073
+		sort($tables);
1074
+
1075
+		return strtolower(implode('_', $tables));
1076
+	}
1077
+
1078
+	/**
1079
+	 * Get the polymorphic relationship columns.
1080
+	 *
1081
+	 * @param  string $name
1082
+	 * @param  string $type
1083
+	 * @param  string $id
1084
+	 * @return string[]
1085
+	 */
1086
+	protected function getMorphs($name, $type, $id)
1087
+	{
1088
+		$type = $type ?: $name . '_type';
1089
+
1090
+		$id = $id ?: $name . '_id';
1091
+
1092
+		return [$type, $id];
1093
+	}
1094
+
1095
+	/**
1096
+	 * Get the class name for polymorphic relations.
1097
+	 *
1098
+	 * @return string
1099
+	 */
1100
+	public function getMorphClass()
1101
+	{
1102
+		$morphClass = Manager::getInstance()->getMorphMap($this->getClass());
1103
+		return $this->morphClass ?: $morphClass;
1104
+	}
1105
+
1106
+	/**
1107
+	 * Create a new Entity Collection instance.
1108
+	 *
1109
+	 * @param  array $entities
1110
+	 * @return \Analogue\ORM\EntityCollection
1111
+	 */
1112
+	public function newCollection(array $entities = [])
1113
+	{
1114
+		$collection = new EntityCollection($entities, $this);
1115
+		return $collection->keyBy($this->getKeyName());
1116
+	}
1117
+
1118
+	/**
1119
+	 * Process EntityMap parsing at initialization time
1120
+	 *
1121
+	 * @return void
1122
+	 */
1123
+	public function initialize()
1124
+	{
1125
+		$userMethods = $this->getCustomMethods();
1126
+
1127
+		// Parse EntityMap for method based relationship
1128
+		if (count($userMethods) > 0) {
1129
+			$this->relationships = $this->parseMethodsForRelationship($userMethods);
1130
+		}
1131
+
1132
+		// Parse EntityMap for dynamic relationships
1133
+		if (count($this->dynamicRelationships) > 0) {
1134
+			$this->relationships = $this->relationships + $this->getDynamicRelationships();
1135
+		}
1136
+	}
1137
+
1138
+	/**
1139
+	 * Parse every relationships on the EntityMap and sort
1140
+	 * them by type.
1141
+	 *
1142
+	 * @return void
1143
+	 */
1144
+	public function boot()
1145
+	{
1146
+		if (count($this->relationships > 0)) {
1147
+			$this->sortRelationshipsByType();
1148
+		}
1149
+	}
1150
+
1151
+	/**
1152
+	 * Get Methods that has been added in the child class.
1153
+	 *
1154
+	 * @return array
1155
+	 */
1156
+	protected function getCustomMethods()
1157
+	{
1158
+		$mapMethods = get_class_methods($this);
1159
+
1160
+		$parentsMethods = get_class_methods('Analogue\ORM\EntityMap');
1161
+
1162
+		return array_diff($mapMethods, $parentsMethods);
1163
+	}
1164
+
1165
+	/**
1166
+	 * Parse user's class methods for relationships
1167
+	 *
1168
+	 * @param  array $customMethods
1169
+	 * @return array
1170
+	 */
1171
+	protected function parseMethodsForRelationship(array $customMethods)
1172
+	{
1173
+		$relationships = [];
1174
+
1175
+		$class = new ReflectionClass(get_class($this));
1176
+
1177
+		// Get the mapped Entity class, as we will detect relationships
1178
+		// methods by testing that the first argument is type-hinted to
1179
+		// the same class as the mapped Entity.
1180
+		$entityClass = $this->getClass();
1181
+
1182
+		foreach ($customMethods as $methodName) {
1183
+			$method = $class->getMethod($methodName);
1184
+
1185
+			if ($method->getNumberOfParameters() > 0) {
1186
+				$params = $method->getParameters();
1187
+
1188
+				if ($params[0]->getClass() && ($params[0]->getClass()->name == $entityClass || is_subclass_of($entityClass, $params[0]->getClass()->name))) {
1189
+					$relationships[] = $methodName;
1190
+				}
1191
+			}
1192
+		}
1193
+
1194
+		return $relationships;
1195
+	}
1196
+
1197
+	/**
1198
+	 * Sort Relationships methods by type
1199
+	 *
1200
+	 * @return void
1201
+	 */
1202
+	protected function sortRelationshipsByType()
1203
+	{
1204
+		$entityClass = $this->getClass();
1205
+
1206
+		// Instantiate a dummy entity which we will pass to relationship methods.
1207
+		$entity = unserialize(sprintf('O:%d:"%s":0:{}', strlen($entityClass), $entityClass));
1208
+
1209
+		foreach ($this->relationships as $relation) {
1210
+			$relationObject = $this->$relation($entity);
1211
+
1212
+			$class = class_basename(get_class($relationObject));
1213
+
1214
+			if (in_array($class, static::$singleClasses)) {
1215
+				$this->singleRelations[] = $relation;
1216
+			}
1217
+
1218
+			if (in_array($class, static::$manyClasses)) {
1219
+				$this->manyRelations[] = $relation;
1220
+			}
1221
+
1222
+			if (in_array($class, static::$localClasses)) {
1223
+				$this->localRelations[] = $relation;
1224
+			}
1225
+
1226
+			if (in_array($class, static::$foreignClasses)) {
1227
+				$this->foreignRelations[] = $relation;
1228
+			}
1229
+
1230
+			if (in_array($class, static::$pivotClasses)) {
1231
+				$this->pivotRelations[] = $relation;
1232
+			}
1233
+		}
1234
+	}
1235
+
1236
+	/**
1237
+	 * Override this method for custom entity instantiation
1238
+	 *
1239
+	 * @return null
1240
+	 */
1241
+	public function activator()
1242
+	{
1243
+		return null;
1244
+	}
1245
+
1246
+	/**
1247
+	 * Call dynamic relationship, if it exists
1248
+	 *
1249
+	 * @param  string $method
1250
+	 * @param  array  $parameters
1251
+	 * @throws Exception
1252
+	 * @return mixed
1253
+	 */
1254
+	public function __call($method, $parameters)
1255
+	{
1256
+		if (!array_key_exists($method, $this->dynamicRelationships)) {
1257
+			throw new Exception(get_class($this) . " has no method $method");
1258
+		}
1259
+
1260
+		// Add $this to parameters so the closure can call relationship method on the map.
1261
+		$parameters[] = $this;
1262
+
1263
+		return  call_user_func_array([$this->dynamicRelationships[$method], $parameters]);
1264
+	}
1265 1265
 }
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/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.