Skip to content

Commit 084f71e

Browse files
committed
Modified the compilation of wheres, fixes #216
1 parent d849f11 commit 084f71e

File tree

2 files changed

+59
-24
lines changed

2 files changed

+59
-24
lines changed

src/Jenssegers/Mongodb/Query/Builder.php

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -667,78 +667,88 @@ public function convertKey($id)
667667
*/
668668
protected function compileWheres()
669669
{
670-
if (!$this->wheres) return array();
670+
// The where's to compile.
671+
$wheres = $this->wheres ?: array();
671672

672-
// The new list of compiled wheres
673-
$wheres = array();
673+
// We will add all compiled wheres to this array.
674+
$compiled = array();
674675

675-
foreach ($this->wheres as $i => &$where)
676+
foreach ($wheres as $i => &$where)
676677
{
677-
// Make sure the operator is in lowercase
678+
// Make sure the operator is in lowercase.
678679
if (isset($where['operator']))
679680
{
680681
$where['operator'] = strtolower($where['operator']);
681682

682-
// Fix elemMatch
683+
// Fix elemMatch.
683684
if ($where['operator'] == 'elemmatch')
684685
{
685686
$where['operator'] = 'elemMatch';
686687
}
687688
}
688689

689-
// Convert id's
690+
// Convert id's.
690691
if (isset($where['column']) && $where['column'] == '_id')
691692
{
692-
// Multiple values
693+
// Multiple values.
693694
if (isset($where['values']))
694695
{
695696
foreach ($where['values'] as &$value)
696697
{
697698
$value = $this->convertKey($value);
698699
}
699700
}
700-
// Single value
701-
elseif (isset($where['value']))
701+
702+
// Single value.
703+
else if (isset($where['value']))
702704
{
703705
$where['value'] = $this->convertKey($where['value']);
704706
}
705707
}
706708

707-
// Convert dates
709+
// Convert DateTime values to MongoDate.
708710
if (isset($where['value']) && $where['value'] instanceof DateTime)
709711
{
710712
$where['value'] = new MongoDate($where['value']->getTimestamp());
711713
}
712714

713-
// First item of chain
714-
if ($i == 0 && count($this->wheres) > 1 && $where['boolean'] == 'and')
715+
// The next item in a "chain" of wheres devices the boolean of the
716+
// first item. So if we see that there are multiple wheres, we will
717+
// use the operator of the next where.
718+
if ($i == 0 and count($wheres) > 1 and $where['boolean'] == 'and')
715719
{
716-
// Copy over boolean value of next item in chain
717-
$where['boolean'] = $this->wheres[$i+1]['boolean'];
720+
$where['boolean'] = $wheres[$i+1]['boolean'];
718721
}
719722

720-
// Delegate
723+
// We use different methods to compile different wheres.
721724
$method = "compileWhere{$where['type']}";
722-
$compiled = $this->{$method}($where);
725+
$result = $this->{$method}($where);
723726

724-
// Check for or
727+
// Wrap the where with an $or operator.
725728
if ($where['boolean'] == 'or')
726729
{
727-
$compiled = array('$or' => array($compiled));
730+
$result = array('$or' => array($result));
731+
}
732+
733+
// If there are multiple wheres, we will wrap it with $and. This is needed
734+
// to make nested wheres work.
735+
else if (count($wheres) > 1)
736+
{
737+
$result = array('$and' => array($result));
728738
}
729739

730-
// Merge compiled where
731-
$wheres = array_merge_recursive($wheres, $compiled);
740+
// Merge the compiled where with the others.
741+
$compiled = array_merge_recursive($compiled, $result);
732742
}
733743

734-
return $wheres;
744+
return $compiled;
735745
}
736746

737747
protected function compileWhereBasic($where)
738748
{
739749
extract($where);
740750

741-
// Replace like with MongoRegex
751+
// Replace like with a MongoRegex instance.
742752
if ($operator == 'like')
743753
{
744754
$operator = '=';
@@ -751,7 +761,7 @@ protected function compileWhereBasic($where)
751761
$value = new MongoRegex("/$regex/i");
752762
}
753763

754-
if (!isset($operator) || $operator == '=')
764+
if ( ! isset($operator) or $operator == '=')
755765
{
756766
$query = array($column => $value);
757767
}

tests/QueryTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,4 +255,29 @@ public function testWhereRaw()
255255
$this->assertEquals(6, count($users));
256256
}
257257

258+
public function testMultipleOr()
259+
{
260+
$users = User::where(function($query)
261+
{
262+
$query->where('age', 35)->orWhere('age', 33);
263+
})
264+
->where(function($query)
265+
{
266+
$query->where('name', 'John Doe')->orWhere('name', 'Jane Doe');
267+
})->get();
268+
269+
$this->assertEquals(2, count($users));
270+
271+
$users = User::where(function($query)
272+
{
273+
$query->orWhere('age', 35)->orWhere('age', 33);
274+
})
275+
->where(function($query)
276+
{
277+
$query->orWhere('name', 'John Doe')->orWhere('name', 'Jane Doe');
278+
})->get();
279+
280+
$this->assertEquals(2, count($users));
281+
}
282+
258283
}

0 commit comments

Comments
 (0)