diff --git a/src/EloquentJoinBuilder.php b/src/EloquentJoinBuilder.php index c5728fa..f4e4fae 100644 --- a/src/EloquentJoinBuilder.php +++ b/src/EloquentJoinBuilder.php @@ -14,6 +14,9 @@ class EloquentJoinBuilder extends Builder { + //base builder + public $baseBuilder; + //use table alias for join (real table name or uniqid()) private $useTableAlias = false; @@ -26,23 +29,43 @@ class EloquentJoinBuilder extends Builder //store clauses on relation for join public $relationClauses = []; + public function where($column, $operator = null, $value = null, $boolean = 'and') + { + if ($column instanceof \Closure) { + $query = $this->model->newModelQuery(); + $baseBuilderCurrent = $this->baseBuilder ? $this->baseBuilder : $this; + $query->baseBuilder = $baseBuilderCurrent; + + $column($query); + + $this->query->addNestedWhereQuery($query->getQuery(), $boolean); + } else { + $this->query->where(...func_get_args()); + } + + return $this; + } + public function whereJoin($column, $operator = null, $value = null, $boolean = 'and') { - $column = $this->performJoin($column); + $query = $this->baseBuilder ? $this->baseBuilder : $this; + $column = $query->performJoin($column); return $this->where($column, $operator, $value, $boolean); } public function orWhereJoin($column, $operator = null, $value = null) { - $column = $this->performJoin($column); + $query = $this->baseBuilder ? $this->baseBuilder : $this; + $column = $query->performJoin($column); return $this->orWhere($column, $operator, $value); } public function orderByJoin($column, $direction = 'asc', $leftJoin = true) { - $column = $this->performJoin($column, $leftJoin); + $query = $this->baseBuilder ? $this->baseBuilder : $this; + $column = $query->performJoin($column, $leftJoin); return $this->orderBy($column, $direction); } diff --git a/tests/Tests/ClosureTest.php b/tests/Tests/ClosureTest.php new file mode 100644 index 0000000..d08bd46 --- /dev/null +++ b/tests/Tests/ClosureTest.php @@ -0,0 +1,57 @@ +orWhereJoin('order.id', '=', 1) + ->orWhereJoin('order.id', '=', 2); + })->get(); + + $queryTest = 'select "order_items".* + from "order_items" + left join "orders" on "orders"."id" = "order_items"."order_id" + and "orders"."deleted_at" is null + where ("orders"."id" = ? or "orders"."id" = ?) + and "order_items"."deleted_at" is null'; + + $this->assertQueryMatches($queryTest, $this->fetchQuery()); + } + + public function testNestTwo() + { + OrderItem::where(function ($query) { + $query + ->orWhereJoin('order.id', '=', 1) + ->orWhereJoin('order.id', '=', 2) + ->where(function ($query) { + $query->orWhereJoin('order.seller.locationPrimary.id', '=', 3); + }); + })->get(); + + $queryTest = 'select "order_items".* from "order_items" + left join "orders" on "orders"."id" = "order_items"."order_id" + and "orders"."deleted_at" is null + left join "sellers" on "sellers"."id" = "orders"."seller_id" + left join "locations" on "locations"."seller_id" = "sellers"."id" + and "locations"."is_primary" = ? + and "locations"."deleted_at" is null + and locations.id = ( + SELECT id + FROM locations + WHERE locations.seller_id = sellers.id + LIMIT 1 + ) where ("orders"."id" = ? or "orders"."id" = ? + and ("locations"."id" = ?)) + and "order_items"."deleted_at" is null'; + + $this->assertQueryMatches($queryTest, $this->fetchQuery()); + } +}