Skip to content

Commit ab56b1b

Browse files
authored
Merge pull request #6 from Weebly/bugfix-closure-query
Better Eloquent support
2 parents 60cc639 + f630ae1 commit ab56b1b

File tree

2 files changed

+92
-15
lines changed

2 files changed

+92
-15
lines changed

src/Database/EloquentBuilder.php

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
namespace Weebly\Mutate\Database;
44

5-
use Closure;
65
use Illuminate\Support\Str;
76
use Illuminate\Database\Eloquent\Builder;
7+
use Illuminate\Database\Query\Expression;
88

99
class EloquentBuilder extends Builder
1010
{
@@ -18,34 +18,87 @@ class EloquentBuilder extends Builder
1818
*/
1919
public function where($column, $operator = null, $value = null, $boolean = 'and')
2020
{
21-
if ($column instanceof Closure) {
22-
return parent::where($column, $operator, $value, $boolean);
23-
}
21+
$bindings = $this->query->bindings;
22+
23+
parent::where($column, $operator, $value, $boolean);
24+
25+
// Remove the last item of the array
26+
$where = array_pop($this->query->wheres);
2427

25-
if (func_num_args() === 2) {
26-
$value = $operator;
27-
$operator = '=';
28+
if ($where['type'] === 'Nested') {
29+
// Add where statement back and return
30+
$this->query->wheres[] = $where;
31+
32+
return $this;
2833
}
2934

30-
$mutatedColumn = $this->getUnqualifiedColumnName($column);
31-
$value = $this->model->serializeAttribute($mutatedColumn, $value);
35+
// Get the column name
36+
$mutatedColumn = $this->getUnqualifiedColumnName($where['column']);
37+
38+
// Modify the values
39+
$where['value'] = $this->model->serializeAttribute($mutatedColumn, $where['value']);
3240

33-
return parent::where($mutatedColumn, $operator, $value, $boolean);
41+
// Add where statement back
42+
$this->query->wheres[] = $where;
43+
44+
// Add the mutated bindings
45+
if (! $where['value'] instanceof Expression) {
46+
// Reset the bindings to the previous value
47+
$this->query->bindings = $bindings;
48+
49+
// Add the mutated bindings back
50+
$this->addBinding($where['value'], 'where');
51+
}
52+
53+
return $this;
3454
}
3555

3656
/**
3757
* {@inheritdoc}
3858
*/
3959
public function whereIn($column, $values, $boolean = 'and', $not = false)
4060
{
41-
$mutatedColumn = $this->getUnqualifiedColumnName($column);
61+
$bindings = $this->query->bindings;
62+
63+
parent::whereIn($column, $values, $boolean, $not);
4264

65+
// Remove the last item of the array
66+
$where = array_pop($this->query->wheres);
67+
68+
if ($where['type'] === 'Nested') {
69+
// Add where statement back and return
70+
$this->query->wheres[] = $where;
71+
72+
return $this;
73+
}
74+
75+
// Get the column name
76+
$mutatedColumn = $this->getUnqualifiedColumnName($where['column']);
77+
78+
// Loop over all values and mutate them
4379
$mutatedValues = [];
44-
foreach ($values as $value) {
80+
foreach ($where['values'] as $value) {
4581
$mutatedValues[] = $this->model->serializeAttribute($mutatedColumn, $value);
4682
}
4783

48-
return parent::whereIn($column, $mutatedValues, $boolean, $not);
84+
// Modify the values
85+
$where['values'] = $mutatedValues;
86+
87+
// Add where statement back
88+
$this->query->wheres[] = $where;
89+
90+
// Loop over all the mutated values and add the bindings
91+
foreach ($mutatedValues as $value) {
92+
if (! $value instanceof Expression) {
93+
// Reset the bindings to the previous value
94+
$this->query->bindings = $bindings;
95+
96+
// Add the mutated bindings back
97+
$this->addBinding($value, 'where');
98+
}
99+
}
100+
101+
return $this;
49102
}
50103

51104
/**

tests/Integration/MutatorTest.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ protected function getEnvironmentSetUp($app)
3131

3232
$app->singleton('mutator', function (Application $app) {
3333
$mutator = new MutatorProvider();
34-
$default_mutators = require realpath(__DIR__.'/../../config/config.php');
35-
$default_mutators = $default_mutators['enabled'];
34+
$default_mutators = (require realpath(__DIR__.'/../../config/config.php'))['enabled'];
3635

3736
$mutator->registerMutators($default_mutators);
3837

@@ -136,6 +135,22 @@ public function test_timestamps()
136135
$this->assertTrue(ctype_digit($values->created_at));
137136
$this->assertTrue(ctype_digit($values->updated_at));
138137
}
138+
139+
public function test_where_closure()
140+
{
141+
$id = Uuid::uuid1()->toString();
142+
$location = 'Foo';
143+
(new TestModel())->create(['id' => $id, 'name' => 'A chair', 'location' => $location])->save();
144+
145+
$model = TestModel::where('name', '=', 'A chair')
146+
->where(function ($q) use ($id) {
147+
$q->where('id', '=', $id)
148+
->orWhere('id', '=', Uuid::uuid1()->toString());
149+
})->get();
150+
151+
$this->assertEquals(1, count($model));
152+
$this->assertEquals($id, $model[0]->id);
153+
}
139154
}
140155

141156
class TestModel extends Model
@@ -176,10 +191,19 @@ class TestModel extends Model
176191

177192
class TimestampedModel extends Model
178193
{
194+
/**
195+
* {@inheritdoc}
196+
*/
179197
protected $table = 'timestamped_model';
180198

199+
/**
200+
* {@inheritdoc}
201+
*/
181202
protected $guarded = [];
182203

204+
/**
205+
* {@inheritdoc}
206+
*/
183207
protected $mutate = [
184208
'created_at' => 'unix_timestamp',
185209
'updated_at' => 'unix_timestamp',

0 commit comments

Comments
 (0)