@@ -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 }
0 commit comments