BelongsToMorph   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 124
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 4
dl 0
loc 124
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 6 2
A getMorphs() 0 8 3
A build() 0 26 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cortex\Foundation\Relations;
6
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Eloquent\Builder;
9
use Illuminate\Database\Eloquent\Relations\Relation;
10
use Illuminate\Database\Eloquent\Relations\BelongsTo;
11
12
class BelongsToMorph extends BelongsTo
13
{
14
    /**
15
     * The name of the polymorphic relation.
16
     *
17
     * @var string
18
     */
19
    protected $morphName;
20
21
    /**
22
     * The type of the polymorphic relation.
23
     *
24
     * @var string
25
     */
26
    protected $morphType;
27
28
    /**
29
     * Create a new belongs to relationship instance.
30
     *
31
     * @param \Illuminate\Database\Eloquent\Builder $query
32
     * @param \Illuminate\Database\Eloquent\Model   $parent
33
     * @param string                                $name
34
     * @param string                                $type
35
     * @param string                                $foreignKey
36
     * @param string                                $ownerKey
37
     * @param string                                $relation
38
     *
39
     * @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...
40
     */
41
    public function __construct(Builder $query, Model $parent, $name, $type, $foreignKey, $ownerKey, $relation)
42
    {
43
        $this->morphName = $name;
44
        $this->morphType = $type;
45
46
        parent::__construct($query, $parent, $foreignKey, $ownerKey, $relation);
47
    }
48
49
    /**
50
     * Add the constraints for a relationship query.
51
     *
52
     * @param \Illuminate\Database\Eloquent\Builder $query
53
     * @param \Illuminate\Database\Eloquent\Builder $parent
54
     * @param array|mixed                           $columns
55
     *
56
     * @return \Illuminate\Database\Eloquent\Builder
57
     */
58
    public function getRelationQuery(Builder $query, Builder $parent, $columns = ['*'])
59
    {
60
        $table = $this->getParent()->getTable();
61
        $query = parent::getRelationQuery($query, $parent, $columns);
62
63
        return $query->where("{$table}.{$this->morphType}", '=', $this->morphName);
64
    }
65
66
    /**
67
     * Get the results of the relationship.
68
     *
69
     * @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...
70
     */
71
    public function getResults()
72
    {
73
        if ($this->getParent()->{$this->morphType} === $this->morphName) {
74
            return $this->query->first();
75
        }
76
    }
77
78
    /**
79
     * Get the polymorphic relationship columns.
80
     *
81
     * @param string $name
82
     * @param string $type
83
     * @param string $id
84
     *
85
     * @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...
86
     */
87
    protected static function getMorphs($name, $type, $id)
88
    {
89
        $type = $type ?: $name.'_type';
90
91
        $id = $id ?: $name.'_id';
92
93
        return [$type, $id];
94
    }
95
96
    /**
97
     * Define an inverse morph relationship.
98
     *
99
     * @param Model  $parent
100
     * @param string $related
101
     * @param string $name
102
     * @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...
103
     * @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...
104
     * @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...
105
     * @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...
106
     *
107
     * @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...
108
     */
109
    public static function build(Model $parent, $related, $name, $type = null, $id = null, $otherKey = null, $relation = null)
110
    {
111
        // If no relation name was given, we will use this debug backtrace to extract
112
        // the calling method's name and use that as the relationship name as most
113
        // of the time this will be what we desire to use for the relationships.
114
        if (is_null($relation)) {
115
            [$current, $caller] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
0 ignored issues
show
Bug introduced by
The variable $current does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $caller does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
116
117
            $relation = $caller['function'];
118
        }
119
120
        $morphName = array_get(array_flip(Relation::morphMap()), $related, $related);
0 ignored issues
show
Deprecated Code introduced by
The function array_get() has been deprecated with message: Arr::get() should be used directly instead. Will be removed in Laravel 6.0.

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
121
122
        [$type, $id] = self::getMorphs(snake_case($name), $type, $id);
0 ignored issues
show
Deprecated Code introduced by
The function snake_case() has been deprecated with message: Str::snake() should be used directly instead. Will be removed in Laravel 6.0.

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
123
124
        $instance = new $related();
125
126
        // Once we have the foreign key names, we'll just create a new Eloquent query
127
        // for the related models and returns the relationship instance which will
128
        // actually be responsible for retrieving and hydrating every relations.
129
        $query = $instance->newQuery();
130
131
        $otherKey = $otherKey ?: $instance->getKeyName();
132
133
        return new self($query, $parent, $morphName, $type, $id, $otherKey, $relation);
134
    }
135
}
136