Passed
Push — master ( 2ca0db...611668 )
by Jonas
02:02
created

hasOneOrManyDeepFromReverse()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 13
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 25
ccs 14
cts 14
cp 1
crap 4
rs 9.8333
1
<?php
2
3
namespace Staudenmeir\EloquentHasManyDeep\Traits;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Database\Eloquent\Relations\Pivot;
7
use Staudenmeir\EloquentHasManyDeep\HasManyDeep;
8
9
trait ReversesRelationships
10
{
11
    /**
12
     * Define a has-many-deep relationship by reversing an existing deep relationship.
13
     *
14
     * @param \Staudenmeir\EloquentHasManyDeep\HasManyDeep $relation
15
     * @return \Staudenmeir\EloquentHasManyDeep\HasManyDeep
16
     */
17 2
    public function hasManyDeepFromReverse(HasManyDeep $relation)
18
    {
19 2
        return $this->hasManyDeep(...$this->hasOneOrManyDeepFromReverse($relation));
0 ignored issues
show
Bug introduced by
The method hasManyDeep() does not exist on Staudenmeir\EloquentHasM...s\ReversesRelationships. Did you maybe mean hasManyDeepFromReverse()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

19
        return $this->/** @scrutinizer ignore-call */ hasManyDeep(...$this->hasOneOrManyDeepFromReverse($relation));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
20
    }
21
22
    /**
23
     * Define a has-one-deep relationship by reversing an existing deep relationship.
24
     *
25
     * @param \Staudenmeir\EloquentHasManyDeep\HasManyDeep $relation
26
     * @return \Staudenmeir\EloquentHasManyDeep\HasOneDeep
27
     */
28 3
    public function hasOneDeepFromReverse(HasManyDeep $relation)
29
    {
30 3
        return $this->hasOneDeep(...$this->hasOneOrManyDeepFromReverse($relation));
0 ignored issues
show
Bug introduced by
The method hasOneDeep() does not exist on Staudenmeir\EloquentHasM...s\ReversesRelationships. Did you maybe mean hasOneDeepFromReverse()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

30
        return $this->/** @scrutinizer ignore-call */ hasOneDeep(...$this->hasOneOrManyDeepFromReverse($relation));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
31
    }
32
33
    /**
34
     * Prepare a has-one-deep or has-many-deep relationship by reversing an existing deep relationship.
35
     *
36
     * @param \Staudenmeir\EloquentHasManyDeep\HasManyDeep $relation
37
     * @return array
38
     */
39 5
    protected function hasOneOrManyDeepFromReverse(HasManyDeep $relation): array
40
    {
41 5
        $related = $relation->getFarParent()::class;
42
43 5
        $through = [];
44
45 5
        foreach (array_reverse($relation->getThroughParents()) as $throughParent) {
46 5
            $through[] = $this->hasOneOrManyDeepFromReverseThroughClass($throughParent);
47
        }
48
49 5
        $foreignKeys = array_map(
50 5
            fn ($key) => is_string($key) ? end(...[explode('.', $key)]) : $key,
0 ignored issues
show
Bug introduced by
array(explode('.', $key)) is expanded, but the parameter $array of end() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

50
            fn ($key) => is_string($key) ? end(/** @scrutinizer ignore-type */ ...[explode('.', $key)]) : $key,
Loading history...
51 5
            array_reverse(
52 5
                $relation->getLocalKeys()
53
            )
54
        );
55
56 5
        $localKeys = array_map(
57 5
            fn ($key) => is_string($key) ? end(...[explode('.', $key)]) : $key,
0 ignored issues
show
Bug introduced by
array(explode('.', $key)) is expanded, but the parameter $array of end() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

57
            fn ($key) => is_string($key) ? end(/** @scrutinizer ignore-type */ ...[explode('.', $key)]) : $key,
Loading history...
58 5
            array_reverse(
59 5
                $relation->getForeignKeys()
60
            )
61
        );
62
63 5
        return [$related, $through, $foreignKeys, $localKeys];
64
    }
65
66
    /**
67
     * Prepare a has-one-deep or has-many-deep relationship through class.
68
     *
69
     * @param \Illuminate\Database\Eloquent\Model $throughParent
70
     * @return string
71
     */
72 5
    protected function hasOneOrManyDeepFromReverseThroughClass(Model $throughParent): string
73
    {
74 5
        $table = $throughParent->getTable();
75
76 5
        $segments = preg_split('/\s+as\s+/i', $table);
77
78 5
        if ($throughParent instanceof Pivot) {
79 2
            if (isset($segments[1])) {
80 1
                $class = $throughParent::class . " as $segments[1]";
81
            } else {
82 2
                $class = $table;
83
            }
84
        } else {
85 5
            $class = $throughParent::class;
86
87 5
            if (isset($segments[1])) {
88 1
                $class .= " as $segments[1]";
89 4
            } elseif ($table !== (new $throughParent())->getTable()) {
90 1
                $class .= " from $table";
91
            }
92
        }
93
94 5
        return $class;
95
    }
96
}
97