Skip to content

Commit af4a50d

Browse files
authored
Merge pull request #23 from kirschbaum-development/disable-soft-deletes
Added the ability to disable soft deletes
2 parents 8e593a2 + d4c8487 commit af4a50d

File tree

6 files changed

+195
-50
lines changed

6 files changed

+195
-50
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
All notable changes to `eloquent-power-joins` will be documented in this file.
44

5+
## 2.1.0 - 2020-09
6+
- Added the ability to include trashed models in join clauses;
7+
58
## 2.0.0 - 2020-09
69
- Introduced trait that has to be used by models;
710
- Automatically applying extra relationship conditions;

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,22 @@ When joining any models which uses the `SoftDeletes` trait, the following condit
184184
and "users"."deleted_at" is null
185185
```
186186

187+
In case you want to include trashed models, you can call the `->withTrashed()` method in the join callback.
188+
189+
```php
190+
UserProfile::joinRelationship('users', function ($join) {
191+
$join->withTrashed();
192+
});
193+
```
194+
195+
You can also call the `onlyTrashed` model as well:
196+
197+
```php
198+
UserProfile::joinRelationship('users', function ($join) {
199+
$join->onlyTrashed();
200+
});
201+
```
202+
187203
#### Extra conditions defined in relationships
188204

189205
If you have extra conditions in your relationship definitions, they will get automatically applied for you.

src/Mixins/RelationshipsExtraMethods.php

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@ class RelationshipsExtraMethods
1919
*/
2020
public function performJoinForEloquentPowerJoins()
2121
{
22-
return function ($builder, $joinType = 'leftJoin', $callback = null, $alias = null) {
22+
return function ($builder, $joinType = 'leftJoin', $callback = null, $alias = null, bool $disableExtraConditions = false) {
2323
if ($this instanceof BelongsToMany) {
24-
return $this->performJoinForEloquentPowerJoinsForBelongsToMany($builder, $joinType, $callback, $alias);
24+
return $this->performJoinForEloquentPowerJoinsForBelongsToMany($builder, $joinType, $callback, $alias, $disableExtraConditions);
2525
} elseif ($this instanceof MorphOneOrMany) {
26-
$this->performJoinForEloquentPowerJoinsForMorph($builder, $joinType, $callback, $alias);
26+
$this->performJoinForEloquentPowerJoinsForMorph($builder, $joinType, $callback, $alias, $disableExtraConditions);
2727
} elseif ($this instanceof HasMany || $this instanceof HasOne) {
28-
return $this->performJoinForEloquentPowerJoinsForHasMany($builder, $joinType, $callback, $alias);
28+
return $this->performJoinForEloquentPowerJoinsForHasMany($builder, $joinType, $callback, $alias, $disableExtraConditions);
2929
} elseif ($this instanceof HasManyThrough) {
30-
return $this->performJoinForEloquentPowerJoinsForHasManyThrough($builder, $joinType, $callback, $alias);
30+
return $this->performJoinForEloquentPowerJoinsForHasManyThrough($builder, $joinType, $callback, $alias, $disableExtraConditions);
3131
} else {
32-
return $this->performJoinForEloquentPowerJoinsForBelongsTo($builder, $joinType, $callback, $alias);
32+
return $this->performJoinForEloquentPowerJoinsForBelongsTo($builder, $joinType, $callback, $alias, $disableExtraConditions);
3333
}
3434
};
3535
}
@@ -39,11 +39,11 @@ public function performJoinForEloquentPowerJoins()
3939
*/
4040
protected function performJoinForEloquentPowerJoinsForBelongsTo()
4141
{
42-
return function ($query, $joinType, $callback = null, $alias = null) {
42+
return function ($query, $joinType, $callback = null, $alias = null, bool $disableExtraConditions = false) {
4343
$joinedTable = $this->query->getModel()->getTable();
4444
$parentTable = $this->getTableOrAliasForModel($this->parent, $this->parent->getTable());
4545

46-
$query->{$joinType}($joinedTable, function ($join) use ($callback, $joinedTable, $parentTable, $alias) {
46+
$query->{$joinType}($joinedTable, function ($join) use ($callback, $joinedTable, $parentTable, $alias, $disableExtraConditions) {
4747
if ($alias) {
4848
$join->as($alias);
4949
}
@@ -54,11 +54,13 @@ protected function performJoinForEloquentPowerJoinsForBelongsTo()
5454
"{$joinedTable}.{$this->ownerKey}"
5555
);
5656

57-
if ($this->usesSoftDeletes($this->query->getModel())) {
57+
if ($disableExtraConditions === false && $this->usesSoftDeletes($this->query->getModel())) {
5858
$join->whereNull("{$joinedTable}.{$this->query->getModel()->getDeletedAtColumn()}");
5959
}
6060

61-
$this->applyExtraConditions($join);
61+
if ($disableExtraConditions === false) {
62+
$this->applyExtraConditions($join);
63+
}
6264

6365
if ($callback && is_callable($callback)) {
6466
$callback($join);
@@ -72,7 +74,7 @@ protected function performJoinForEloquentPowerJoinsForBelongsTo()
7274
*/
7375
protected function performJoinForEloquentPowerJoinsForBelongsToMany()
7476
{
75-
return function ($builder, $joinType, $callback = null, $alias = null) {
77+
return function ($builder, $joinType, $callback = null, $alias = null, bool $disableExtraConditions = false) {
7678
[$alias1, $alias2] = $alias;
7779

7880
$joinedTable = $alias1 ?: $this->getTable();
@@ -94,7 +96,7 @@ protected function performJoinForEloquentPowerJoinsForBelongsToMany()
9496
}
9597
});
9698

97-
$builder->{$joinType}($this->getModel()->getTable(), function ($join) use ($callback, $joinedTable, $alias2) {
99+
$builder->{$joinType}($this->getModel()->getTable(), function ($join) use ($callback, $joinedTable, $alias2, $disableExtraConditions) {
98100
if ($alias2) {
99101
$join->as($alias2);
100102
}
@@ -105,12 +107,14 @@ protected function performJoinForEloquentPowerJoinsForBelongsToMany()
105107
"{$joinedTable}.{$this->getRelatedPivotKeyName()}"
106108
);
107109

108-
if ($this->usesSoftDeletes($this->query->getModel())) {
110+
if ($disableExtraConditions === false && $this->usesSoftDeletes($this->query->getModel())) {
109111
$join->whereNull($this->query->getModel()->getQualifiedDeletedAtColumn());
110112
}
111113

112114
// applying any extra conditions to the belongs to many relationship
113-
$this->applyExtraConditions($join);
115+
if ($disableExtraConditions === false) {
116+
$this->applyExtraConditions($join);
117+
}
114118

115119
if (is_array($callback) && isset($callback[$this->getModel()->getTable()])) {
116120
$callback[$this->getModel()->getTable()]($join);
@@ -126,19 +130,21 @@ protected function performJoinForEloquentPowerJoinsForBelongsToMany()
126130
*/
127131
protected function performJoinForEloquentPowerJoinsForMorph()
128132
{
129-
return function ($builder, $joinType, $callback = null) {
130-
$builder->{$joinType}($this->getModel()->getTable(), function ($join) use ($callback) {
133+
return function ($builder, $joinType, $callback = null, $alias = null, bool $disableExtraConditions = false) {
134+
$builder->{$joinType}($this->getModel()->getTable(), function ($join) use ($callback, $disableExtraConditions) {
131135
$join->on(
132136
"{$this->getModel()->getTable()}.{$this->getForeignKeyName()}",
133137
'=',
134138
"{$this->parent->getTable()}.{$this->localKey}"
135139
)->where($this->getMorphType(), '=', $this->getMorphClass());
136140

137-
if ($this->usesSoftDeletes($this->query->getModel())) {
141+
if ($disableExtraConditions === false && $this->usesSoftDeletes($this->query->getModel())) {
138142
$join->whereNull($this->query->getModel()->getQualifiedDeletedAtColumn());
139143
}
140144

141-
$this->applyExtraConditions($join);
145+
if ($disableExtraConditions === false) {
146+
$this->applyExtraConditions($join);
147+
}
142148

143149
if ($callback && is_callable($callback)) {
144150
$callback($join);
@@ -154,11 +160,11 @@ protected function performJoinForEloquentPowerJoinsForMorph()
154160
*/
155161
protected function performJoinForEloquentPowerJoinsForHasMany()
156162
{
157-
return function ($builder, $joinType, $callback = null, $alias = null) {
163+
return function ($builder, $joinType, $callback = null, $alias = null, bool $disableExtraConditions = false) {
158164
$joinedTable = $alias ?: $this->query->getModel()->getTable();
159165
$parentTable = $this->getTableOrAliasForModel($this->parent, $this->parent->getTable());
160166

161-
$builder->{$joinType}($this->query->getModel()->getTable(), function ($join) use ($callback, $joinedTable, $parentTable, $alias) {
167+
$builder->{$joinType}($this->query->getModel()->getTable(), function ($join) use ($callback, $joinedTable, $parentTable, $alias, $disableExtraConditions) {
162168
if ($alias) {
163169
$join->as($alias);
164170
}
@@ -169,13 +175,15 @@ protected function performJoinForEloquentPowerJoinsForHasMany()
169175
"{$parentTable}.{$this->localKey}"
170176
);
171177

172-
if ($this->usesSoftDeletes($this->query->getModel())) {
178+
if ($disableExtraConditions === false && $this->usesSoftDeletes($this->query->getModel())) {
173179
$join->whereNull(
174180
"{$joinedTable}.{$this->query->getModel()->getDeletedAtColumn()}"
175181
);
176182
}
177183

178-
$this->applyExtraConditions($join);
184+
if ($disableExtraConditions === false) {
185+
$this->applyExtraConditions($join);
186+
}
179187

180188
if ($callback && is_callable($callback)) {
181189
$callback($join);
@@ -189,12 +197,12 @@ protected function performJoinForEloquentPowerJoinsForHasMany()
189197
*/
190198
protected function performJoinForEloquentPowerJoinsForHasManyThrough()
191199
{
192-
return function ($builder, $joinType, $callback = null, $alias = null) {
200+
return function ($builder, $joinType, $callback = null, $alias = null, bool $disableExtraConditions = false) {
193201
[$alias1, $alias2] = $alias;
194202
$throughTable = $alias1 ?: $this->getThroughParent()->getTable();
195203
$farTable = $alias2 ?: $this->getModel()->getTable();
196204

197-
$builder->{$joinType}($this->getThroughParent()->getTable(), function (PowerJoinClause $join) use ($callback, $throughTable, $alias1) {
205+
$builder->{$joinType}($this->getThroughParent()->getTable(), function (PowerJoinClause $join) use ($callback, $throughTable, $alias1, $disableExtraConditions) {
198206
if ($alias1) {
199207
$join->as($alias1);
200208
}
@@ -205,10 +213,14 @@ protected function performJoinForEloquentPowerJoinsForHasManyThrough()
205213
$this->getQualifiedLocalKeyName()
206214
);
207215

208-
if ($this->usesSoftDeletes($this->getThroughParent())) {
216+
if ($disableExtraConditions === false && $this->usesSoftDeletes($this->getThroughParent())) {
209217
$join->whereNull($this->getThroughParent()->getQualifiedDeletedAtColumn());
210218
}
211219

220+
if ($disableExtraConditions === false) {
221+
$this->applyExtraConditions($join);
222+
}
223+
212224
if (is_array($callback) && isset($callback[$this->getThroughParent()->getTable()])) {
213225
$callback[$this->getThroughParent()->getTable()]($join);
214226
}
@@ -350,6 +362,10 @@ public function getPowerJoinExistenceCompareKey()
350362
return $this->getExistenceCompareKey();
351363
}
352364

365+
if ($this instanceof HasManyThrough) {
366+
return $this->getQualifiedFirstKeyName();
367+
}
368+
353369
if ($this instanceof BelongsToMany) {
354370
return $this->getExistenceCompareKey();
355371
}

src/PowerJoinClause.php

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
namespace Kirschbaum\PowerJoins;
44

5-
use Illuminate\Database\Eloquent\Model;
6-
use Illuminate\Database\Query\Builder;
7-
use Illuminate\Database\Query\JoinClause;
85
use Illuminate\Support\Str;
96
use InvalidArgumentException;
7+
use Illuminate\Database\Query\Builder;
8+
use Illuminate\Database\Eloquent\Model;
9+
use Illuminate\Database\Query\JoinClause;
10+
use Illuminate\Database\Eloquent\SoftDeletes;
1011

1112
class PowerJoinClause extends JoinClause
1213
{
@@ -60,7 +61,7 @@ public function as(string $alias)
6061
return $this;
6162
}
6263

63-
public function on($first, $operator = null, $second = null, $boolean = 'and')
64+
public function on($first, $operator = null, $second = null, $boolean = 'and'): self
6465
{
6566
parent::on($first, $operator, $second, $boolean);
6667
$this->useTableAliasInConditions();
@@ -73,6 +74,9 @@ public function getModel()
7374
return $this->model;
7475
}
7576

77+
/**
78+
* Apply the table alias in the existing join conditions.
79+
*/
7680
protected function useTableAliasInConditions()
7781
{
7882
if (! $this->alias || ! $this->model) {
@@ -118,6 +122,46 @@ public function where($column, $operator = null, $value = null, $boolean = 'and'
118122
return parent::where($column, $operator, $value, $boolean);
119123
}
120124

125+
/**
126+
* Remove the soft delete condition in case the model implements soft deletes.
127+
*/
128+
public function withTrashed(): self
129+
{
130+
if (! in_array(SoftDeletes::class, class_uses_recursive($this->getModel()))) {
131+
return $this;
132+
}
133+
134+
$this->wheres = array_filter($this->wheres, function ($where) {
135+
if ($where['type'] === 'Null' && Str::contains($where['column'], $this->getModel()->getDeletedAtColumn())) {
136+
return false;
137+
}
138+
139+
return true;
140+
});
141+
142+
return $this;
143+
}
144+
145+
/**
146+
* Remove the soft delete condition in case the model implements soft deletes.
147+
*/
148+
public function onlyTrashed(): self
149+
{
150+
if (! in_array(SoftDeletes::class, class_uses_recursive($this->getModel()))) {
151+
return $this;
152+
}
153+
154+
$this->wheres = array_map(function ($where) {
155+
if ($where['type'] === 'Null' && Str::contains($where['column'], $this->getModel()->getDeletedAtColumn())) {
156+
$where['type'] = 'NotNull';
157+
}
158+
159+
return $where;
160+
}, $this->wheres);
161+
162+
return $this;
163+
}
164+
121165
public function __call($name, $arguments)
122166
{
123167
$scope = 'scope' . ucfirst($name);

0 commit comments

Comments
 (0)