Completed
Push — develop ( 8e3ca1...f11a4f )
by Abdelrahman
02:14
created

BelongsToMorph   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 6
dl 0
loc 125
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A getRelationQuery() 0 7 1
A getResults() 0 8 2
A getMorphs() 0 8 3
B build() 0 26 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cortex\Foundation\Relations;
6
7
use Illuminate\Support\Arr;
8
use Illuminate\Support\Str;
9
use Illuminate\Database\Eloquent\Model;
10
use Illuminate\Database\Eloquent\Builder;
11
use Illuminate\Database\Eloquent\Relations\Relation;
12
use Illuminate\Database\Eloquent\Relations\BelongsTo;
13
14
class BelongsToMorph extends BelongsTo
15
{
16
    /**
17
     * The name of the polymorphic relation.
18
     *
19
     * @var string
20
     */
21
    protected $morphName;
22
23
    /**
24
     * The type of the polymorphic relation.
25
     *
26
     * @var string
27
     */
28
    protected $morphType;
29
30
    /**
31
     * Create a new belongs to relationship instance.
32
     *
33
     * @param  \Illuminate\Database\Eloquent\Builder  $query
34
     * @param  \Illuminate\Database\Eloquent\Model  $parent
35
     * @param  string  $name
36
     * @param  string  $type
37
     * @param  string  $foreignKey
38
     * @param  string  $ownerKey
39
     * @param  string  $relation
40
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
41
     */
42
    public function __construct(Builder $query, Model $parent, $name, $type, $foreignKey, $ownerKey, $relation)
43
    {
44
        $this->morphName = $name;
45
        $this->morphType = $type;
46
47
        parent::__construct($query, $parent, $foreignKey, $ownerKey, $relation);
48
    }
49
50
    /**
51
     * Add the constraints for a relationship query.
52
     *
53
     * @param  \Illuminate\Database\Eloquent\Builder $query
54
     * @param  \Illuminate\Database\Eloquent\Builder $parent
55
     * @param  array|mixed                           $columns
56
     *
57
     * @return \Illuminate\Database\Eloquent\Builder
58
     */
59
    public function getRelationQuery(Builder $query, Builder $parent, $columns = ['*'])
60
    {
61
        $table = $this->getParent()->getTable();
62
        $query = parent::getRelationQuery($query, $parent, $columns);
63
64
        return $query->where("{$table}.{$this->morphType}", '=', $this->morphName);
65
    }
66
67
    /**
68
     * Get the results of the relationship.
69
     *
70
     * @return mixed
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use object|null.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
71
     */
72
    public function getResults()
73
    {
74
        if ($this->getParent()->{$this->morphType} === $this->morphName) {
75
            return $this->query->first();
76
        }
77
78
        return null;
79
    }
80
81
    /**
82
     * Get the polymorphic relationship columns.
83
     *
84
     * @param  string $name
85
     * @param  string $type
86
     * @param  string $id
87
     *
88
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use string[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
89
     */
90
    protected static function getMorphs($name, $type, $id)
91
    {
92
        $type = $type ?: $name.'_type';
93
94
        $id = $id ?: $name.'_id';
95
96
        return [$type, $id];
97
    }
98
99
    /**
100
     * Define an inverse morph relationship.
101
     *
102
     * @param  Model  $parent
103
     * @param  string $related
104
     * @param  string $name
105
     * @param  string $type
0 ignored issues
show
Documentation introduced by
Should the type for parameter $type not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
106
     * @param  string $id
0 ignored issues
show
Documentation introduced by
Should the type for parameter $id not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
107
     * @param  string $otherKey
0 ignored issues
show
Documentation introduced by
Should the type for parameter $otherKey not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
108
     * @param  string $relation
0 ignored issues
show
Documentation introduced by
Should the type for parameter $relation not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
109
     *
110
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use BelongsToMorph.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
111
     */
112
    public static function build(Model $parent, $related, $name, $type = null, $id = null, $otherKey = null, $relation = null)
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 126 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
113
    {
114
        // If no relation name was given, we will use this debug backtrace to extract
115
        // the calling method's name and use that as the relationship name as most
116
        // of the time this will be what we desire to use for the relationships.
117
        if (is_null($relation)) {
118
            list($current, $caller) = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
0 ignored issues
show
Unused Code introduced by
The assignment to $current is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
119
120
            $relation = $caller['function'];
121
        }
122
123
        $morphName = Arr::get(array_flip(Relation::morphMap()), $related, $related);
124
125
        list($type, $id) = self::getMorphs(Str::snake($name), $type, $id);
126
127
        $instance = new $related;
128
129
        // Once we have the foreign key names, we'll just create a new Eloquent query
130
        // for the related models and returns the relationship instance which will
131
        // actually be responsible for retrieving and hydrating every relations.
132
        $query = $instance->newQuery();
133
134
        $otherKey = $otherKey ?: $instance->getKeyName();
135
136
        return new BelongsToMorph($query, $parent, $morphName, $type, $id, $otherKey, $relation);
137
    }
138
}
139