| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -463,7 +463,7 @@ public function onDelete(Closure $callback) | |||
| 463 | 463 | */ | |
| 464 | 464 | public function getModels($columns = ['*']) | |
| 465 | 465 | { | |
| 466 | - $results = $this->applyScopes()->getQuery()->get($columns); | ||
| 466 | + $results = $this->toBase()->get($columns); | ||
| 467 | 467 | ||
| 468 | 468 | $connection = $this->model->getConnectionName(); | |
| 469 | 469 | ||
@@ -892,8 +892,8 @@ protected function callScope($scope, $parameters) | |||
| 892 | 892 | ||
| 893 | 893 | $result = call_user_func_array([$this->model, $scope], $parameters) ?: $this; | |
| 894 | 894 | ||
| 895 | - if ($this->shouldNestWheresForScope($originalWhereCount, $query)) { | ||
| 896 | - $this->nestWheresForScope($query, [0, $originalWhereCount, count($query->wheres)]); | ||
| 895 | + if ($this->shouldNestWheresForScope($query, $originalWhereCount)) { | ||
| 896 | + $this->nestWheresForScope($query, $originalWhereCount); | ||
| 897 | 897 | } | |
| 898 | 898 | ||
| 899 | 899 | return $result; | |
@@ -919,7 +919,7 @@ public function applyScopes() | |||
| 919 | 919 | // query as their own isolated nested where statement and avoid issues. | |
| 920 | 920 | $originalWhereCount = count($query->wheres); | |
| 921 | 921 | ||
| 922 | - $whereCounts = [0, $originalWhereCount]; | ||
| 922 | + $whereCounts = [$originalWhereCount]; | ||
| 923 | 923 | ||
| 924 | 924 | foreach ($this->scopes as $scope) { | |
| 925 | 925 | $this->applyScope($scope, $builder); | |
@@ -930,8 +930,8 @@ public function applyScopes() | |||
| 930 | 930 | $whereCounts[] = count($query->wheres); | |
| 931 | 931 | } | |
| 932 | 932 | ||
| 933 | - if ($this->shouldNestWheresForScope($originalWhereCount, $query)) { | ||
| 934 | - $this->nestWheresForScope($query, array_unique($whereCounts)); | ||
| 933 | + if ($this->shouldNestWheresForScope($query, $originalWhereCount)) { | ||
| 934 | + $this->nestWheresForScope($query, $whereCounts); | ||
| 935 | 935 | } | |
| 936 | 936 | ||
| 937 | 937 | return $builder; | |
@@ -956,23 +956,23 @@ protected function applyScope($scope, $builder) | |||
| 956 | 956 | /** | |
| 957 | 957 | * Determine if the scope added after the given offset should be nested. | |
| 958 | 958 | * | |
| 959 | - * @param int $originalWhereCount | ||
| 960 | 959 | * @param \Illuminate\Database\Query\Builder $query | |
| 960 | + * @param int $originalWhereCount | ||
| 961 | 961 | * @return bool | |
| 962 | 962 | */ | |
| 963 | - protected function shouldNestWheresForScope($originalWhereCount, QueryBuilder $query) | ||
| 963 | + protected function shouldNestWheresForScope(QueryBuilder $query, $originalWhereCount) | ||
| 964 | 964 | { | |
| 965 | 965 | return $originalWhereCount && count($query->wheres) > $originalWhereCount; | |
| 966 | 966 | } | |
| 967 | 967 | ||
| 968 | 968 | /** | |
| 969 | - * Nest where conditions of the builder and each global scope. | ||
| 969 | + * Nest where conditions by slicing them at the given where count. | ||
| 970 | 970 | * | |
| 971 | 971 | * @param \Illuminate\Database\Query\Builder $query | |
| 972 | - * @param array $offsets | ||
| 972 | + * @param int|array $whereCounts | ||
| 973 | 973 | * @return void | |
| 974 | 974 | */ | |
| 975 | - protected function nestWheresForScope(QueryBuilder $query, array $whereCounts) | ||
| 975 | + protected function nestWheresForScope(QueryBuilder $query, $whereCounts) | ||
| 976 | 976 | { | |
| 977 | 977 | // Here, we totally remove all of the where clauses since we are going to | |
| 978 | 978 | // rebuild them as nested queries by slicing the groups of wheres into | |
@@ -981,33 +981,56 @@ protected function nestWheresForScope(QueryBuilder $query, array $whereCounts) | |||
| 981 | 981 | ||
| 982 | 982 | $query->wheres = []; | |
| 983 | 983 | ||
| 984 | - // We will take the first offset (typically 0) of where clauses and start | ||
| 985 | - // slicing out every scope's where clauses into their own nested where | ||
| 986 | - // groups for improved isolation of every scope's added constraints. | ||
| 987 | - $previousCount = array_shift($whereCounts); | ||
| 984 | + // We will construct where offsets by adding the outer most offsets to the | ||
| 985 | + // collection (0 and total where count) while also flattening the array | ||
| 986 | + // and extracting unique values, ensuring that all wheres are sliced. | ||
| 987 | + $whereOffsets = collect([0, $whereCounts, count($allWheres)])->flatten()->unique(); | ||
| 988 | + | ||
| 989 | + $sliceFrom = $whereOffsets->shift(); | ||
| 990 | + | ||
| 991 | + foreach ($whereOffsets as $sliceTo) { | ||
| 992 | + $this->sliceWhereConditions($query, $allWheres, $sliceFrom, $sliceTo); | ||
| 988 | 993 | ||
| 989 | - foreach ($whereCounts as $whereCount) { | ||
| 990 | - $query->wheres[] = $this->sliceWhereConditions( | ||
| 991 | - $allWheres, $previousCount, $whereCount - $previousCount | ||
| 992 | - ); | ||
| 994 | + $sliceFrom = $sliceTo; | ||
| 995 | + } | ||
| 996 | + } | ||
| 993 | 997 | ||
| 994 | - $previousCount = $whereCount; | ||
| 998 | + /** | ||
| 999 | + * Create a slice of where conditions at the given offsets and nest them if needed. | ||
| 1000 | + * | ||
| 1001 | + * @param \Illuminate\Database\Query\Builder $query | ||
| 1002 | + * @param array $wheres | ||
| 1003 | + * @param int $sliceFrom | ||
| 1004 | + * @param int $sliceTo | ||
| 1005 | + * @return void | ||
| 1006 | + */ | ||
| 1007 | + protected function sliceWhereConditions(QueryBuilder $query, array $wheres, $sliceFrom, $sliceTo) | ||
| 1008 | + { | ||
| 1009 | + $whereSlice = array_slice($wheres, $sliceFrom, $sliceTo - $sliceFrom); | ||
| 1010 | + | ||
| 1011 | + $whereBooleans = collect($whereSlice)->pluck('boolean'); | ||
| 1012 | + | ||
| 1013 | + // Here we'll check if the given subset of where clauses contains any "or" | ||
| 1014 | + // booleans and in this case create a nested where expression. That way | ||
| 1015 | + // we don't add any unnecessary nesting thus keeping the query clean. | ||
| 1016 | + if ($whereBooleans->contains('or')) { | ||
| 1017 | + $query->wheres[] = $this->nestWhereSlice($whereSlice); | ||
| 1018 | + } else { | ||
| 1019 | + $query->wheres = array_merge($query->wheres, $whereSlice); | ||
| 995 | 1020 | } | |
| 996 | 1021 | } | |
| 997 | 1022 | ||
| 998 | 1023 | /** | |
| 999 | - * Create a where array with sliced where conditions. | ||
| 1024 | + * Create a where array with nested where conditions. | ||
| 1000 | 1025 | * | |
| 1001 | - * @param array $allWheres | ||
| 1002 | - * @param int $offset | ||
| 1003 | - * @param int $length | ||
| 1026 | + * @param array $whereSubset | ||
| 1004 | 1027 | * @return array | |
| 1005 | 1028 | */ | |
| 1006 | - protected function sliceWhereConditions($allWheres, $offset, $length) | ||
| 1029 | + protected function nestWhereSlice($whereSubset) | ||
| 1007 | 1030 | { | |
| 1008 | 1031 | $whereGroup = $this->getQuery()->forNestedWhere(); | |
| 1009 | 1032 | ||
| 1010 | - $whereGroup->wheres = array_slice($allWheres, $offset, $length); | ||
| 1033 | + $whereGroup->wheres = $whereSubset; | ||
| 1011 | 1034 | ||
| 1012 | 1035 | return ['type' => 'Nested', 'query' => $whereGroup, 'boolean' => 'and']; | |
| 1013 | 1036 | } | |
@@ -1136,7 +1159,7 @@ public function __call($method, $parameters) | |||
| 1136 | 1159 | } | |
| 1137 | 1160 | ||
| 1138 | 1161 | if (in_array($method, $this->passthru)) { | |
| 1139 | - return call_user_func_array([$this->applyScopes()->getQuery(), $method], $parameters); | ||
| 1162 | + return call_user_func_array([$this->toBase(), $method], $parameters); | ||
| 1140 | 1163 | } | |
| 1141 | 1164 | ||
| 1142 | 1165 | call_user_func_array([$this->query, $method], $parameters); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -399,7 +399,7 @@ public function testRealNestedWhereWithScopes() | |||
| 399 | 399 | $model = new EloquentBuilderTestNestedStub; | |
| 400 | 400 | $this->mockConnectionForModel($model, 'SQLite'); | |
| 401 | 401 | $query = $model->newQuery()->where('foo', '=', 'bar')->where(function ($query) { $query->where('baz', '>', 9000); }); | |
| 402 | - $this->assertEquals('select * from "table" where ("foo" = ? and ("baz" > ?)) and ("table"."deleted_at" is null)', $query->toSql()); | ||
| 402 | + $this->assertEquals('select * from "table" where "foo" = ? and ("baz" > ?) and "table"."deleted_at" is null', $query->toSql()); | ||
| 403 | 403 | $this->assertEquals(['bar', 9000], $query->getBindings()); | |
| 404 | 404 | } | |
| 405 | 405 | ||
@@ -408,7 +408,7 @@ public function testRealNestedWhereWithMultipleScopesAndOneDeadScope() | |||
| 408 | 408 | $model = new EloquentBuilderTestNestedStub; | |
| 409 | 409 | $this->mockConnectionForModel($model, 'SQLite'); | |
| 410 | 410 | $query = $model->newQuery()->empty()->where('foo', '=', 'bar')->empty()->where(function ($query) { $query->empty()->where('baz', '>', 9000); }); | |
| 411 | - $this->assertEquals('select * from "table" where ("foo" = ? and ("baz" > ?)) and ("table"."deleted_at" is null)', $query->toSql()); | ||
| 411 | + $this->assertEquals('select * from "table" where "foo" = ? and ("baz" > ?) and "table"."deleted_at" is null', $query->toSql()); | ||
| 412 | 412 | $this->assertEquals(['bar', 9000], $query->getBindings()); | |
| 413 | 413 | } | |
| 414 | 414 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -70,7 +70,7 @@ public function testGlobalScopesWithOrWhereConditionsAreNested() | |||
| 70 | 70 | $model = new EloquentClosureGlobalScopesWithOrTestModel(); | |
| 71 | 71 | ||
| 72 | 72 | $query = $model->newQuery()->where('col1', 'val1')->orWhere('col2', 'val2'); | |
| 73 | - $this->assertEquals('select "email", "password" from "table" where ("col1" = ? or "col2" = ?) and ("email" = ? or "email" = ?) and ("active" = ?) order by "name" asc', $query->toSql()); | ||
| 73 | + $this->assertEquals('select "email", "password" from "table" where ("col1" = ? or "col2" = ?) and ("email" = ? or "email" = ?) and "active" = ? order by "name" asc', $query->toSql()); | ||
| 74 | 74 | $this->assertEquals(['val1', 'val2', 'taylor@gmail.com', 'someone@else.com', 1], $query->getBindings()); | |
| 75 | 75 | } | |
| 76 | 76 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments