Skip to content

Commit e274839

Browse files
authored
Merge 1bc27d0 into 3566015
2 parents 3566015 + 1bc27d0 commit e274839

File tree

1 file changed

+86
-7
lines changed

1 file changed

+86
-7
lines changed

src/Engines/QueryBuilderEngine.php

Lines changed: 86 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -272,18 +272,97 @@ protected function getEagerLoads()
272272
protected function compileRelationSearch($query, $relation, $column, $keyword)
273273
{
274274
$myQuery = clone $this->query;
275-
$relationType = $myQuery->getModel()->{$relation}();
276-
$myQuery->orWhereHas($relation, function ($builder) use ($column, $keyword, $query, $relationType) {
277-
$builder->select($this->connection->raw('count(1)'));
278-
$this->compileQuerySearch($builder, $column, $keyword, '');
275+
276+
/**
277+
* For compile nested relation, we need store all nested relation as array
278+
* and reverse order to apply where query.
279+
*
280+
* With this method we can create nested sub query with properly relation.
281+
*/
282+
283+
/**
284+
* Store all relation data that require in next step
285+
*/
286+
$relationChunk = [];
287+
288+
/**
289+
* Store last eloquent query builder for get next relation.
290+
*/
291+
$lastQuery = $query;
292+
293+
$relations = explode('.', $relation);
294+
$lastRelation = end($relations);
295+
foreach ($relations as $relation) {
296+
$relationType = $myQuery->getModel()->{$relation}();
297+
$myQuery->orWhereHas($relation, function ($builder) use (
298+
$column,
299+
$keyword,
300+
$query,
301+
$relationType,
302+
$relation,
303+
$lastRelation,
304+
&$relationChunk,
305+
&$lastQuery
306+
) {
307+
$builder->select($this->connection->raw('count(1)'));
308+
309+
// We will perform search on last relation only.
310+
if ($relation == $lastRelation) {
311+
$this->compileQuerySearch($builder, $column, $keyword, '');
312+
}
313+
314+
// Put require object to next step!!
315+
$relationChunk[$relation] = [
316+
'builder' => $builder,
317+
'relationType' => $relationType,
318+
'query' => $lastQuery
319+
];
320+
321+
// This is trick make sub query.
322+
$lastQuery = $builder;
323+
});
324+
325+
// This is trick to make nested relation by pass previous relation to be next query eloquent builder
326+
$myQuery = $relationType;
327+
}
328+
329+
/**
330+
* Reverse them all
331+
*/
332+
$relationChunk = array_reverse($relationChunk, true);
333+
334+
/**
335+
* Create valuable for use in check last relation
336+
*/
337+
end($relationChunk);
338+
$lastRelation = key($relationChunk);
339+
reset($relationChunk);
340+
341+
/**
342+
* Walking ...
343+
*/
344+
foreach ($relationChunk as $relation => $chunk) {
345+
// Prepare variables
346+
$builder = $chunk['builder'];
347+
$relationType = $chunk['relationType'];
348+
$query = $chunk['query'];
279349
$builder = "({$builder->toSql()}) >= 1";
280350

351+
// Check if it last relation we will use orWhereRaw
352+
if ($lastRelation == $relation) {
353+
$relationMethod = "orWhereRaw";
354+
} else {
355+
// For case parent relation of nested relation.
356+
// We must use and for properly query and get correct result
357+
$relationMethod = "whereRaw";
358+
}
359+
281360
if ($relationType instanceof MorphToMany) {
282-
$query->orWhereRaw($builder, [$relationType->getMorphClass(), $this->prepareKeyword($keyword)]);
361+
$query->{$relationMethod}($builder, [$relationType->getMorphClass(), $this->prepareKeyword($keyword)]);
283362
} else {
284-
$query->orWhereRaw($builder, [$this->prepareKeyword($keyword)]);
363+
$query->{$relationMethod}($builder, [$this->prepareKeyword($keyword)]);
285364
}
286-
});
365+
}
287366
}
288367

289368
/**

0 commit comments

Comments
 (0)