Completed
Push — 5.1 ( 64105d...5947be )
by Rémi
08:21 queued 04:00
created
src/Relationships/HasManyThrough.php 1 patch
Indentation   +310 added lines, -310 removed lines patch added patch discarded remove patch
@@ -9,314 +9,314 @@
 block discarded – undo
9 9
 
10 10
 class HasManyThrough extends Relationship
11 11
 {
12
-    /**
13
-     * The distance parent Entity instance.
14
-     *
15
-     * @var \Analogue\ORM\Entity
16
-     */
17
-    protected $farParent;
18
-
19
-    /**
20
-     * The far parent map instance
21
-     *
22
-     * @var \Analogue\ORM\EntityMap
23
-     */
24
-    protected $farParentMap;
25
-
26
-    /**
27
-     * The near key on the relationship.
28
-     *
29
-     * @var string
30
-     */
31
-    protected $firstKey;
32
-
33
-    /**
34
-     * The far key on the relationship.
35
-     *
36
-     * @var string
37
-     */
38
-    protected $secondKey;
39
-
40
-    /**
41
-     * Create a new has many relationship instance.
42
-     *
43
-     * @param Mapper                  $mapper
44
-     * @param \Analogue\ORM\Mappable  $farParent
45
-     * @param \Analogue\ORM\EntityMap $parentMap
46
-     * @param string                  $firstKey
47
-     * @param string                  $secondKey
48
-     * @throws \Analogue\ORM\Exceptions\MappingException
49
-     */
50
-    public function __construct(Mapper $mapper, $farParent, $parentMap, $firstKey, $secondKey)
51
-    {
52
-        $this->firstKey = $firstKey;
53
-        $this->secondKey = $secondKey;
54
-        $this->farParent = $farParent;
55
-
56
-        $this->farParentMap = $mapper->getManager()->mapper($farParent)->getEntityMap();
57
-        $parentInstance = $mapper->getManager()->mapper($parentMap->getClass())->newInstance();
58
-
59
-        parent::__construct($mapper, $parentInstance);
60
-    }
61
-
62
-    /**
63
-     * @param $related
64
-     * @return mixed
65
-     */
66
-    public function attachTo($related)
67
-    {
68
-        // N/A
69
-    }
70
-
71
-    /**
72
-     * @param $related
73
-     * @return mixed
74
-     */
75
-    public function detachFrom($related)
76
-    {
77
-        // N/A
78
-    }
79
-
80
-    /**
81
-     * Set the base constraints on the relation query.
82
-     *
83
-     * @return void
84
-     */
85
-    public function addConstraints()
86
-    {
87
-        $parentTable = $this->parentMap->getTable();
88
-
89
-        $this->setJoin();
90
-
91
-        if (static::$constraints) {
92
-            $farParentKeyName = $this->farParentMap->getKeyName();
93
-
94
-            $this->query->where(
95
-                $parentTable . '.' . $this->firstKey,
96
-                '=',
97
-                $this->farParent->getEntityAttribute($farParentKeyName)
98
-            );
99
-        }
100
-    }
101
-
102
-    /**
103
-     * Add the constraints for a relationship count query.
104
-     *
105
-     * @param  Query $query
106
-     * @param  Query $parent
107
-     * @return Query
108
-     */
109
-    public function getRelationCountQuery(Query $query, Query $parent)
110
-    {
111
-        $parentTable = $this->parentMap->getTable();
112
-
113
-        $this->setJoin($query);
114
-
115
-        $query->select(new Expression('count(*)'));
116
-
117
-        $key = $this->wrap($parentTable . '.' . $this->firstKey);
118
-
119
-        return $query->where($this->getHasCompareKey(), '=', new Expression($key));
120
-    }
121
-
122
-    /**
123
-     * Set the join clause on the query.
124
-     *
125
-     * @param  null|Query $query
126
-     * @return void
127
-     */
128
-    protected function setJoin(Query $query = null)
129
-    {
130
-        $query = $query ?: $this->query;
131
-
132
-        $foreignKey = $this->relatedMap->getTable() . '.' . $this->secondKey;
133
-
134
-        $query->join($this->parentMap->getTable(), $this->getQualifiedParentKeyName(), '=', $foreignKey);
135
-    }
136
-
137
-    /**
138
-     * Set the constraints for an eager load of the relation.
139
-     *
140
-     * @param  array $entities
141
-     * @return void
142
-     */
143
-    public function addEagerConstraints(array $entities)
144
-    {
145
-        $table = $this->parentMap->getTable();
146
-
147
-        $this->query->whereIn($table . '.' . $this->firstKey, $this->getKeys($entities));
148
-    }
149
-
150
-    /**
151
-     * Initialize the relation on a set of entities.
152
-     *
153
-     * @param  \Analogue\ORM\Entity[] $entities
154
-     * @param  string                 $relation
155
-     * @return \Analogue\ORM\Entity[]
156
-     */
157
-    public function initRelation(array $entities, $relation)
158
-    {
159
-        foreach ($entities as $entity) {
160
-            $entity->setEntityAttribute($relation, $this->relatedMap->newCollection());
161
-        }
162
-
163
-        return $entities;
164
-    }
165
-
166
-    /**
167
-     * Match the eagerly loaded results to their parents.
168
-     *
169
-     * @param  \Analogue\ORM\Entity[] $entities
170
-     * @param  EntityCollection       $results
171
-     * @param  string                 $relation
172
-     * @return \Analogue\ORM\Entity[]
173
-     */
174
-    public function match(array $entities, EntityCollection $results, $relation)
175
-    {
176
-        $dictionary = $this->buildDictionary($results);
177
-
178
-        $relatedKey = $this->relatedMap->getKeyName();
179
-
180
-        $cache = $this->parentMapper->getEntityCache();
181
-
182
-        // Once we have the dictionary we can simply spin through the parent entities to
183
-        // link them up with their children using the keyed dictionary to make the
184
-        // matching very convenient and easy work. Then we'll just return them.
185
-        foreach ($entities as $entity) {
186
-            $key = $entity->getEntityAttribute($relatedKey);
187
-
188
-            if (isset($dictionary[$key])) {
189
-                $value = $this->relatedMap->newCollection($dictionary[$key]);
190
-
191
-                $entity->setEntityAttribute($relation, $value);
192
-
193
-                $cache->cacheLoadedRelationResult($entity, $relation, $value, $this);
194
-            }
195
-        }
196
-
197
-        return $entities;
198
-    }
199
-
200
-    /**
201
-     * Build model dictionary keyed by the relation's foreign key.
202
-     *
203
-     * @param  EntityCollection $results
204
-     * @return array
205
-     */
206
-    protected function buildDictionary(EntityCollection $results)
207
-    {
208
-        $dictionary = [];
209
-
210
-        $foreign = $this->firstKey;
211
-
212
-        // First we will create a dictionary of entities keyed by the foreign key of the
213
-        // relationship as this will allow us to quickly access all of the related
214
-        // entities without having to do nested looping which will be quite slow.
215
-        foreach ($results as $result) {
216
-            $dictionary[$result->{$foreign}][] = $result;
217
-        }
218
-
219
-        return $dictionary;
220
-    }
221
-
222
-    /**
223
-     * Get the results of the relationship.
224
-     *
225
-     * @param  $relation
226
-     * @return EntityCollection
227
-     */
228
-    public function getResults($relation)
229
-    {
230
-        $results = $this->query->get();
231
-
232
-        $this->cacheRelation($results, $relation);
233
-
234
-        return $results;
235
-    }
236
-
237
-    /**
238
-     * Execute the query as a "select" statement.
239
-     *
240
-     * @param  array $columns
241
-     * @return EntityCollection
242
-     */
243
-    public function get($columns = ['*'])
244
-    {
245
-        // First we'll add the proper select columns onto the query so it is run with
246
-        // the proper columns. Then, we will get the results and hydrate out pivot
247
-        // entities with the result of those columns as a separate model relation.
248
-        $select = $this->getSelectColumns($columns);
249
-
250
-        $entities = $this->query->addSelect($select)->getEntities();
251
-
252
-        // If we actually found entities we will also eager load any relationships that
253
-        // have been specified as needing to be eager loaded. This will solve the
254
-        // n + 1 query problem for the developer and also increase performance.
255
-        if (count($entities) > 0) {
256
-            $entities = $this->query->eagerLoadRelations($entities);
257
-        }
258
-
259
-        return $this->relatedMap->newCollection($entities);
260
-    }
261
-
262
-    /**
263
-     * Set the select clause for the relation query.
264
-     *
265
-     * @param  array $columns
266
-     * @return BelongsToMany
267
-     */
268
-    protected function getSelectColumns(array $columns = ['*'])
269
-    {
270
-        if ($columns == ['*']) {
271
-            $columns = [$this->relatedMap->getTable() . '.*'];
272
-        }
273
-
274
-        return array_merge($columns, [$this->parentMap->getTable() . '.' . $this->firstKey]);
275
-    }
276
-
277
-    /**
278
-     * Get a paginator for the "select" statement.
279
-     *
280
-     * @param  int   $perPage
281
-     * @param  array $columns
282
-     * @return \Illuminate\Pagination\LengthAwarePaginator
283
-     */
284
-    public function paginate($perPage = null, $columns = ['*'])
285
-    {
286
-        $this->query->addSelect($this->getSelectColumns($columns));
287
-
288
-        return $this->query->paginate($perPage, $columns);
289
-    }
290
-
291
-    /**
292
-     * Get the key name of the parent model.
293
-     *
294
-     * @return string
295
-     */
296
-    protected function getQualifiedParentKeyName()
297
-    {
298
-        return $this->parentMap->getQualifiedKeyName();
299
-    }
300
-
301
-    /**
302
-     * Get the key for comparing against the parent key in "has" query.
303
-     *
304
-     * @return string
305
-     */
306
-    public function getHasCompareKey()
307
-    {
308
-        return $this->farParentMap->getQualifiedKeyName();
309
-    }
310
-
311
-    /**
312
-     * Run synchronization content if needed by the
313
-     * relation type.
314
-     *
315
-     * @param  array $actualContent
316
-     * @return void
317
-     */
318
-    public function sync(array $entities)
319
-    {
320
-        // N/A
321
-    }
12
+	/**
13
+	 * The distance parent Entity instance.
14
+	 *
15
+	 * @var \Analogue\ORM\Entity
16
+	 */
17
+	protected $farParent;
18
+
19
+	/**
20
+	 * The far parent map instance
21
+	 *
22
+	 * @var \Analogue\ORM\EntityMap
23
+	 */
24
+	protected $farParentMap;
25
+
26
+	/**
27
+	 * The near key on the relationship.
28
+	 *
29
+	 * @var string
30
+	 */
31
+	protected $firstKey;
32
+
33
+	/**
34
+	 * The far key on the relationship.
35
+	 *
36
+	 * @var string
37
+	 */
38
+	protected $secondKey;
39
+
40
+	/**
41
+	 * Create a new has many relationship instance.
42
+	 *
43
+	 * @param Mapper                  $mapper
44
+	 * @param \Analogue\ORM\Mappable  $farParent
45
+	 * @param \Analogue\ORM\EntityMap $parentMap
46
+	 * @param string                  $firstKey
47
+	 * @param string                  $secondKey
48
+	 * @throws \Analogue\ORM\Exceptions\MappingException
49
+	 */
50
+	public function __construct(Mapper $mapper, $farParent, $parentMap, $firstKey, $secondKey)
51
+	{
52
+		$this->firstKey = $firstKey;
53
+		$this->secondKey = $secondKey;
54
+		$this->farParent = $farParent;
55
+
56
+		$this->farParentMap = $mapper->getManager()->mapper($farParent)->getEntityMap();
57
+		$parentInstance = $mapper->getManager()->mapper($parentMap->getClass())->newInstance();
58
+
59
+		parent::__construct($mapper, $parentInstance);
60
+	}
61
+
62
+	/**
63
+	 * @param $related
64
+	 * @return mixed
65
+	 */
66
+	public function attachTo($related)
67
+	{
68
+		// N/A
69
+	}
70
+
71
+	/**
72
+	 * @param $related
73
+	 * @return mixed
74
+	 */
75
+	public function detachFrom($related)
76
+	{
77
+		// N/A
78
+	}
79
+
80
+	/**
81
+	 * Set the base constraints on the relation query.
82
+	 *
83
+	 * @return void
84
+	 */
85
+	public function addConstraints()
86
+	{
87
+		$parentTable = $this->parentMap->getTable();
88
+
89
+		$this->setJoin();
90
+
91
+		if (static::$constraints) {
92
+			$farParentKeyName = $this->farParentMap->getKeyName();
93
+
94
+			$this->query->where(
95
+				$parentTable . '.' . $this->firstKey,
96
+				'=',
97
+				$this->farParent->getEntityAttribute($farParentKeyName)
98
+			);
99
+		}
100
+	}
101
+
102
+	/**
103
+	 * Add the constraints for a relationship count query.
104
+	 *
105
+	 * @param  Query $query
106
+	 * @param  Query $parent
107
+	 * @return Query
108
+	 */
109
+	public function getRelationCountQuery(Query $query, Query $parent)
110
+	{
111
+		$parentTable = $this->parentMap->getTable();
112
+
113
+		$this->setJoin($query);
114
+
115
+		$query->select(new Expression('count(*)'));
116
+
117
+		$key = $this->wrap($parentTable . '.' . $this->firstKey);
118
+
119
+		return $query->where($this->getHasCompareKey(), '=', new Expression($key));
120
+	}
121
+
122
+	/**
123
+	 * Set the join clause on the query.
124
+	 *
125
+	 * @param  null|Query $query
126
+	 * @return void
127
+	 */
128
+	protected function setJoin(Query $query = null)
129
+	{
130
+		$query = $query ?: $this->query;
131
+
132
+		$foreignKey = $this->relatedMap->getTable() . '.' . $this->secondKey;
133
+
134
+		$query->join($this->parentMap->getTable(), $this->getQualifiedParentKeyName(), '=', $foreignKey);
135
+	}
136
+
137
+	/**
138
+	 * Set the constraints for an eager load of the relation.
139
+	 *
140
+	 * @param  array $entities
141
+	 * @return void
142
+	 */
143
+	public function addEagerConstraints(array $entities)
144
+	{
145
+		$table = $this->parentMap->getTable();
146
+
147
+		$this->query->whereIn($table . '.' . $this->firstKey, $this->getKeys($entities));
148
+	}
149
+
150
+	/**
151
+	 * Initialize the relation on a set of entities.
152
+	 *
153
+	 * @param  \Analogue\ORM\Entity[] $entities
154
+	 * @param  string                 $relation
155
+	 * @return \Analogue\ORM\Entity[]
156
+	 */
157
+	public function initRelation(array $entities, $relation)
158
+	{
159
+		foreach ($entities as $entity) {
160
+			$entity->setEntityAttribute($relation, $this->relatedMap->newCollection());
161
+		}
162
+
163
+		return $entities;
164
+	}
165
+
166
+	/**
167
+	 * Match the eagerly loaded results to their parents.
168
+	 *
169
+	 * @param  \Analogue\ORM\Entity[] $entities
170
+	 * @param  EntityCollection       $results
171
+	 * @param  string                 $relation
172
+	 * @return \Analogue\ORM\Entity[]
173
+	 */
174
+	public function match(array $entities, EntityCollection $results, $relation)
175
+	{
176
+		$dictionary = $this->buildDictionary($results);
177
+
178
+		$relatedKey = $this->relatedMap->getKeyName();
179
+
180
+		$cache = $this->parentMapper->getEntityCache();
181
+
182
+		// Once we have the dictionary we can simply spin through the parent entities to
183
+		// link them up with their children using the keyed dictionary to make the
184
+		// matching very convenient and easy work. Then we'll just return them.
185
+		foreach ($entities as $entity) {
186
+			$key = $entity->getEntityAttribute($relatedKey);
187
+
188
+			if (isset($dictionary[$key])) {
189
+				$value = $this->relatedMap->newCollection($dictionary[$key]);
190
+
191
+				$entity->setEntityAttribute($relation, $value);
192
+
193
+				$cache->cacheLoadedRelationResult($entity, $relation, $value, $this);
194
+			}
195
+		}
196
+
197
+		return $entities;
198
+	}
199
+
200
+	/**
201
+	 * Build model dictionary keyed by the relation's foreign key.
202
+	 *
203
+	 * @param  EntityCollection $results
204
+	 * @return array
205
+	 */
206
+	protected function buildDictionary(EntityCollection $results)
207
+	{
208
+		$dictionary = [];
209
+
210
+		$foreign = $this->firstKey;
211
+
212
+		// First we will create a dictionary of entities keyed by the foreign key of the
213
+		// relationship as this will allow us to quickly access all of the related
214
+		// entities without having to do nested looping which will be quite slow.
215
+		foreach ($results as $result) {
216
+			$dictionary[$result->{$foreign}][] = $result;
217
+		}
218
+
219
+		return $dictionary;
220
+	}
221
+
222
+	/**
223
+	 * Get the results of the relationship.
224
+	 *
225
+	 * @param  $relation
226
+	 * @return EntityCollection
227
+	 */
228
+	public function getResults($relation)
229
+	{
230
+		$results = $this->query->get();
231
+
232
+		$this->cacheRelation($results, $relation);
233
+
234
+		return $results;
235
+	}
236
+
237
+	/**
238
+	 * Execute the query as a "select" statement.
239
+	 *
240
+	 * @param  array $columns
241
+	 * @return EntityCollection
242
+	 */
243
+	public function get($columns = ['*'])
244
+	{
245
+		// First we'll add the proper select columns onto the query so it is run with
246
+		// the proper columns. Then, we will get the results and hydrate out pivot
247
+		// entities with the result of those columns as a separate model relation.
248
+		$select = $this->getSelectColumns($columns);
249
+
250
+		$entities = $this->query->addSelect($select)->getEntities();
251
+
252
+		// If we actually found entities we will also eager load any relationships that
253
+		// have been specified as needing to be eager loaded. This will solve the
254
+		// n + 1 query problem for the developer and also increase performance.
255
+		if (count($entities) > 0) {
256
+			$entities = $this->query->eagerLoadRelations($entities);
257
+		}
258
+
259
+		return $this->relatedMap->newCollection($entities);
260
+	}
261
+
262
+	/**
263
+	 * Set the select clause for the relation query.
264
+	 *
265
+	 * @param  array $columns
266
+	 * @return BelongsToMany
267
+	 */
268
+	protected function getSelectColumns(array $columns = ['*'])
269
+	{
270
+		if ($columns == ['*']) {
271
+			$columns = [$this->relatedMap->getTable() . '.*'];
272
+		}
273
+
274
+		return array_merge($columns, [$this->parentMap->getTable() . '.' . $this->firstKey]);
275
+	}
276
+
277
+	/**
278
+	 * Get a paginator for the "select" statement.
279
+	 *
280
+	 * @param  int   $perPage
281
+	 * @param  array $columns
282
+	 * @return \Illuminate\Pagination\LengthAwarePaginator
283
+	 */
284
+	public function paginate($perPage = null, $columns = ['*'])
285
+	{
286
+		$this->query->addSelect($this->getSelectColumns($columns));
287
+
288
+		return $this->query->paginate($perPage, $columns);
289
+	}
290
+
291
+	/**
292
+	 * Get the key name of the parent model.
293
+	 *
294
+	 * @return string
295
+	 */
296
+	protected function getQualifiedParentKeyName()
297
+	{
298
+		return $this->parentMap->getQualifiedKeyName();
299
+	}
300
+
301
+	/**
302
+	 * Get the key for comparing against the parent key in "has" query.
303
+	 *
304
+	 * @return string
305
+	 */
306
+	public function getHasCompareKey()
307
+	{
308
+		return $this->farParentMap->getQualifiedKeyName();
309
+	}
310
+
311
+	/**
312
+	 * Run synchronization content if needed by the
313
+	 * relation type.
314
+	 *
315
+	 * @param  array $actualContent
316
+	 * @return void
317
+	 */
318
+	public function sync(array $entities)
319
+	{
320
+		// N/A
321
+	}
322 322
 }
Please login to merge, or discard this patch.