Passed
Push — master ( 6cf215...65a336 )
by Jonas
12:16
created

JoinsThroughParents::joinThroughParent()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 34
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 5.0342

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 20
nc 4
nop 6
dl 0
loc 34
ccs 16
cts 18
cp 0.8889
crap 5.0342
rs 9.2888
c 1
b 0
f 0
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 74
    protected function joinThroughParent(Builder $query, Model $throughParent, Model $predecessor, $foreignKey, $localKey, $prefix)
26
    {
27 74
        $table = $throughParent->getTable();
28
29 74
        if ($foreignKey instanceof Closure) {
0 ignored issues
show
introduced by
$foreignKey is never a sub-type of Closure.
Loading history...
30
            $query->join(
31
                $table,
32
                fn (JoinClause $join) => $foreignKey($query, $join)
33
            );
34
        } else {
35 74
            $joins = $this->throughParentJoins($query, $throughParent, $predecessor, $foreignKey, $localKey);
36
37 74
            foreach ($joins as $i => [$first, $second]) {
38 74
                $joins[$i] = [
39 74
                    $throughParent->qualifyColumn($first),
40 74
                    $predecessor->qualifyColumn($prefix.$second),
41
                ];
42
            }
43
44 74
            $query->join(
45
                $table,
46 74
                function (JoinClause $join) use ($joins) {
47 74
                    foreach ($joins as [$first, $second]) {
48 74
                        $join->on($first, '=', $second);
49
                    }
50
                }
51
            );
52
        }
53
54 74
        if ($this->throughParentInstanceSoftDeletes($throughParent)) {
55 41
            $column= $throughParent->getQualifiedDeletedAtColumn();
56
57 41
            $query->withGlobalScope(__CLASS__ . ":$column", function (Builder $query) use ($column) {
58 35
                $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 74
    protected function throughParentJoins(Builder $query, Model $throughParent, Model $predecessor, $foreignKey, $localKey): array
74
    {
75 74
        $joins = [];
76
77 74
        if ($localKey instanceof CompositeKey) {
78 5
            foreach ($localKey->columns as $i => $column) {
79 5
                $joins[] = [$column, $foreignKey->columns[$i]];
80
            }
81
        } else {
82 69
            if (is_array($localKey)) {
83 5
                $query->where($throughParent->qualifyColumn($localKey[0]), '=', $predecessor->getMorphClass());
84
85 5
                $localKey = $localKey[1];
86
            }
87
88 69
            if (is_array($foreignKey)) {
89 5
                $query->where($predecessor->qualifyColumn($foreignKey[0]), '=', $throughParent->getMorphClass());
90
91 5
                $foreignKey = $foreignKey[1];
92
            }
93
94 69
            $joins[] = [$localKey, $foreignKey];
95
        }
96
97 74
        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 74
    public function throughParentInstanceSoftDeletes(Model $instance)
107
    {
108 74
        return in_array(SoftDeletes::class, class_uses_recursive($instance));
109
    }
110
}
111