Completed
Pull Request — master (#221)
by Christopher
11:18 queued 15s
created

MetadataRelationsTrait::addRelationsHook()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 22
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 10
c 2
b 0
f 0
dl 0
loc 22
rs 9.9332
cc 3
nc 4
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: alex
5
 * Date: 13/02/20
6
 * Time: 1:08 PM.
7
 */
8
namespace AlgoWeb\PODataLaravel\Models;
9
10
use Illuminate\Database\Eloquent\Model;
11
use Illuminate\Database\Eloquent\Relations\BelongsTo;
12
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
13
use Illuminate\Database\Eloquent\Relations\MorphMany;
14
use Illuminate\Database\Eloquent\Relations\MorphOne;
15
use Illuminate\Database\Eloquent\Relations\MorphToMany;
16
use Illuminate\Database\Eloquent\Relations\Relation;
17
use Mockery\Mock;
18
use POData\Common\InvalidOperationException;
19
20
trait MetadataRelationsTrait
21
{
22
23
    /**
24
     * Get model's relationships.
25
     *
26
     * @throws InvalidOperationException
27
     * @throws \ReflectionException
28
     * @return array
29
     */
30
    public function getRelationships()
31
    {
32
        return  $this->getRelationshipsFromMethods();
33
    }
34
35
    private $hasUnknownPolymorphic = false;
36
    private $hasKnownPolymorphic = false;
37
    /**
38
     * Is this model the known side of at least one polymorphic relation?
39
     *
40
     * @throws InvalidOperationException
41
     * @throws \ReflectionException
42
     */
43
    public function isKnownPolymorphSide()
44
    {
45
        // isKnownPolymorph needs to be checking KnownPolymorphSide results - if you're checking UnknownPolymorphSide,
46
        // you're turned around
47
        $rels = $this->getRelationshipsFromMethods();
0 ignored issues
show
Unused Code introduced by
The assignment to $rels is dead and can be removed.
Loading history...
48
        return $this->hasKnownPolymorphic;
49
    }
50
51
    /**
52
     * Is this model on the unknown side of at least one polymorphic relation?
53
     *
54
     * @throws InvalidOperationException
55
     * @throws \ReflectionException
56
     */
57
    public function isUnknownPolymorphSide()
58
    {
59
        // isUnknownPolymorph needs to be checking UnknownPolymorphSide results - if you're checking KnownPolymorphSide,
60
        // you're turned around
61
        $rels = $this->getRelationshipsFromMethods();
0 ignored issues
show
Unused Code introduced by
The assignment to $rels is dead and can be removed.
Loading history...
62
        return $this->hasUnknownPolymorphic;
63
    }
64
    /**
65
     * @param  \ReflectionMethod         $method
66
     * @throws InvalidOperationException
67
     * @return string
68
     */
69
    protected function getCodeForMethod(\ReflectionMethod $method) : string
70
    {
71
        $fileName = $method->getFileName();
72
73
        $file = new \SplFileObject($fileName);
74
        $file->seek($method->getStartLine() - 1);
75
        $code = '';
76
        while ($file->key() < $method->getEndLine()) {
77
            $code .= $file->current();
78
            $file->next();
79
        }
80
81
        $code = trim(preg_replace('/\s\s+/', '', $code));
82
        if (false === stripos($code, 'function')) {
83
            $msg = 'Function definition must have keyword \'function\'';
84
            throw new InvalidOperationException($msg);
85
        }
86
        $begin = strpos($code, 'function(');
87
        $code = substr($code, $begin, strrpos($code, '}') - $begin + 1);
88
        $lastCode = $code[strlen($code) - 1];
89
        if ('}' != $lastCode) {
90
            $msg = 'Final character of function definition must be closing brace';
91
            throw new InvalidOperationException($msg);
92
        }
93
        return $code;
94
    }
95
    /**
96
     * @param  Model $model
97
     * @return array
98
     */
99
    protected function getModelClassMethods(Model $model)
100
    {
101
        // TODO: Handle case when Mock::class not present
102
        return array_diff(
103
            get_class_methods($model),
104
            get_class_methods(\Illuminate\Database\Eloquent\Model::class),
105
            get_class_methods(Mock::class),
106
            get_class_methods(MetadataTrait::class)
107
        );
108
    }
109
    /**
110
     * @param bool $biDir
111
     *
112
     * @throws InvalidOperationException
113
     * @throws \ReflectionException
114
     * @return array
115
     */
116
    protected function getRelationshipsFromMethods()
117
    {
118
        /*$biDirVal = true;
119
        $isCached = isset(static::$relationCategories[$biDirVal]) && !empty(static::$relationCategories[$biDirVal]);
120
        if ($isCached) {
121
            return static::$relationCategories[$biDirVal];
122
        }*/
123
        $relationships = [];
124
        /** @var Model $model */
125
        $model = $this;
126
        $methods = $this->getModelClassMethods($model);
127
        foreach ($methods as $method) {
128
            //Use reflection to inspect the code, based on Illuminate/Support/SerializableClosure.php
129
            $reflection = new \ReflectionMethod($model, $method);
130
            $code = $this->getCodeForMethod($reflection);
131
            foreach (static::$relTypes as $relation) {
132
                //Resolve the relation's model to a Relation object.
133
                if (
134
                    !stripos($code, sprintf('$this->%s(', $relation)) ||
135
                    !(($relationObj = $model->$method()) instanceof Relation) ||
136
                    !in_array(MetadataTrait::class, class_uses($relationObj->getRelated()))
137
                ) {
138
                    continue;
139
                }
140
                if (in_array($relation, ['morphedByMany','morphTo'])) {
141
                    $this->hasUnknownPolymorphic = true;
142
                } elseif (in_array($relation, ['morphOne','morphMany','morphToMany'])) {
143
                    $this->hasKnownPolymorphic = true;
144
                }
145
                $relationships[]= $method;
146
            }
147
        }
148
        return $relationships;
149
    }
150
}
151