Skip to content
This repository was archived by the owner on Aug 22, 2023. It is now read-only.

Commit 9ee1e65

Browse files
committed
Fix nested "or not"
1 parent 64f39ea commit 9ee1e65

File tree

2 files changed

+35
-17
lines changed

2 files changed

+35
-17
lines changed

src/Query/Builder.php

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,32 +1002,26 @@ protected function compileWheres(): array
10021002
});
10031003
}
10041004

1005-
$not = false;
1006-
if ($where['boolean'] === 'and not') {
1007-
$where['boolean'] = 'and';
1008-
$not = true;
1009-
} elseif ($where['boolean'] === 'or not') {
1010-
$where['boolean'] = 'or';
1011-
$not = true;
1012-
}
1013-
10141005
// The next item in a "chain" of wheres devices the boolean of the
10151006
// first item. So if we see that there are multiple wheres, we will
10161007
// use the operator of the next where.
1017-
if ($i == 0 && count($wheres) > 1 && $where['boolean'] == 'and') {
1018-
$where['boolean'] = $wheres[$i + 1]['boolean'];
1008+
if ($i == 0 && count($wheres) > 1
1009+
&& str_starts_with($where['boolean'], 'and')
1010+
&& str_starts_with($wheres[$i + 1]['boolean'], 'or')
1011+
) {
1012+
$where['boolean'] = 'or' . (str_ends_with($where['boolean'], 'not') ? ' not' : '');
10191013
}
10201014

10211015
// We use different methods to compile different wheres.
10221016
$method = "compileWhere{$where['type']}";
10231017
$result = $this->{$method}($where);
10241018

1025-
if ($not) {
1019+
if (str_ends_with($where['boolean'], 'not')) {
10261020
$result = ['$not' => $result];
10271021
}
10281022

10291023
// Wrap the where with an $or operator.
1030-
if ($where['boolean'] == 'or') {
1024+
if (str_starts_with($where['boolean'], 'or')) {
10311025
$result = ['$or' => [$result]];
10321026
}
10331027

tests/Query/BuilderTest.php

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,30 @@ public static function provideQueryBuilderToMql(): iterable
6060
fn (Builder $builder) => $builder->where(['foo' => 1, 'bar' => 2]),
6161
];
6262

63+
yield 'nested orWhere and where' => [
64+
['find' => [
65+
['$and' => [
66+
['$or' => [
67+
['$and' => [
68+
['foo' => 1],
69+
['$not' => ['bar' => 2]],
70+
]],
71+
]],
72+
['baz' => 3],
73+
]],
74+
[], // options
75+
]],
76+
fn (Builder $builder) => $builder
77+
->where(
78+
fn (Builder $q) => $q->orWhere(
79+
fn (Builder $q) => $q
80+
->where('foo', 1)
81+
->whereNot('bar', 2)
82+
)
83+
)
84+
->where('baz', 3),
85+
];
86+
6387
yield 'find > date' => [
6488
['find' => [['foo' => ['$gt' => new UTCDateTime($date)]], []]],
6589
fn (Builder $builder) => $builder->where('foo', '>', $date),
@@ -176,10 +200,10 @@ public static function provideQueryBuilderToMql(): iterable
176200

177201
yield 'where or whereNot' => [
178202
['find' => [
179-
[
180-
'$and' => [['name' => 'bar']],
181-
'$or' => [['$not' => ['email' => 'foo']]],
182-
],
203+
['$or' => [
204+
['name' => 'bar'],
205+
['$not' => ['email' => 'foo']]
206+
]],
183207
[], // options
184208
]],
185209
fn (Builder $builder) => $builder

0 commit comments

Comments
 (0)