Passed
Push — master ( 52fd8a...8684f9 )
by Jonas
02:25
created

JoinsThroughParents   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 35
c 1
b 0
f 0
dl 0
loc 97
ccs 33
cts 33
cp 1
rs 10
wmc 11

3 Methods

Rating   Name   Duplication   Size   Complexity  
A throughParentInstanceSoftDeletes() 0 3 1
A throughParentJoins() 0 25 5
A joinThroughParent() 0 34 5
1
<?php
2
3
namespace Staudenmeir\EloquentHasManyDeep\Eloquent\Relations\Traits;
4
5
use Closure;
6
use Illuminate\Database\Eloquent\Builder;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Eloquent\SoftDeletes;
9
use Illuminate\Database\Query\JoinClause;
10
use Staudenmeir\EloquentHasManyDeep\Eloquent\CompositeKey;
11
12
trait JoinsThroughParents
13
{
14
    /**
15
     * Join a through parent table.
16
     *
17
     * @param \Illuminate\Database\Eloquent\Builder $query
18
     * @param \Illuminate\Database\Eloquent\Model $throughParent
19
     * @param \Illuminate\Database\Eloquent\Model $predecessor
20
     * @param \Staudenmeir\EloquentHasManyDeep\Eloquent\CompositeKey|array|string $foreignKey
21
     * @param \Staudenmeir\EloquentHasManyDeep\Eloquent\CompositeKey|array|string $localKey
22
     * @param string $prefix
23
     * @return void
24
     */
25 190
    protected function joinThroughParent(Builder $query, Model $throughParent, Model $predecessor, $foreignKey, $localKey, $prefix)
26
    {
27 190
        $table = $throughParent->getTable();
28
29 190
        if ($foreignKey instanceof Closure) {
0 ignored issues
show
introduced by
$foreignKey is never a sub-type of Closure.
Loading history...
30 7
            $query->join(
31
                $table,
32 7
                fn (JoinClause $join) => $foreignKey($query, $join)
33
            );
34
        } else {
35 183
            $joins = $this->throughParentJoins($query, $throughParent, $predecessor, $foreignKey, $localKey);
36
37 183
            foreach ($joins as $i => [$first, $second]) {
38 183
                $joins[$i] = [
39 183
                    $throughParent->qualifyColumn($first),
40 183
                    $predecessor->qualifyColumn($prefix.$second),
41
                ];
42
            }
43
44 183
            $query->join(
45
                $table,
46 183
                function (JoinClause $join) use ($joins) {
47 183
                    foreach ($joins as [$first, $second]) {
48 183
                        $join->on($first, '=', $second);
49
                    }
50
                }
51
            );
52
        }
53
54 190
        if ($this->throughParentInstanceSoftDeletes($throughParent)) {
55 110
            $column= $throughParent->getQualifiedDeletedAtColumn();
56
57 110
            $query->withGlobalScope(__CLASS__ . ":$column", function (Builder $query) use ($column) {
58 98
                $query->whereNull($column);
59
            });
60
        }
61
    }
62
63
    /**
64
     * Get the joins for a through parent table.
65
     *
66
     * @param \Illuminate\Database\Eloquent\Builder $query
67
     * @param \Illuminate\Database\Eloquent\Model $throughParent
68
     * @param \Illuminate\Database\Eloquent\Model $predecessor
69
     * @param \Staudenmeir\EloquentHasManyDeep\Eloquent\CompositeKey|array|string $foreignKey
70
     * @param \Staudenmeir\EloquentHasManyDeep\Eloquent\CompositeKey|array|string $localKey
71
     * @return array
72
     */
73 183
    protected function throughParentJoins(Builder $query, Model $throughParent, Model $predecessor, $foreignKey, $localKey): array
74
    {
75 183
        $joins = [];
76
77 183
        if ($localKey instanceof CompositeKey) {
78 10
            foreach ($localKey->columns as $i => $column) {
79 10
                $joins[] = [$column, $foreignKey->columns[$i]];
80
            }
81
        } else {
82 173
            if (is_array($localKey)) {
83 10
                $query->where($throughParent->qualifyColumn($localKey[0]), '=', $predecessor->getMorphClass());
84
85 10
                $localKey = $localKey[1];
86
            }
87
88 173
            if (is_array($foreignKey)) {
89 10
                $query->where($predecessor->qualifyColumn($foreignKey[0]), '=', $throughParent->getMorphClass());
90
91 10
                $foreignKey = $foreignKey[1];
92
            }
93
94 173
            $joins[] = [$localKey, $foreignKey];
95
        }
96
97 183
        return $joins;
98
    }
99
100
    /**
101
     * Determine whether a "through" parent instance of the relation uses SoftDeletes.
102
     *
103
     * @param \Illuminate\Database\Eloquent\Model $instance
104
     * @return bool
105
     */
106 190
    public function throughParentInstanceSoftDeletes(Model $instance)
107
    {
108 190
        return in_array(SoftDeletes::class, class_uses_recursive($instance));
109
    }
110
}
111