Passed
Pull Request — master (#221)
by Christopher
06:51 queued 45s
created

MetadataRelationsTrait::getRelationshipsUnknownPolyMorph()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 9
c 2
b 0
f 0
dl 0
loc 17
rs 9.6111
cc 5
nc 9
nop 2
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
    /**
36
     * @param  \ReflectionMethod         $method
37
     * @throws InvalidOperationException
38
     * @return string
39
     */
40
    protected function getCodeForMethod(\ReflectionMethod $method) : string
41
    {
42
        $fileName = $method->getFileName();
43
44
        $file = new \SplFileObject($fileName);
45
        $file->seek($method->getStartLine() - 1);
46
        $code = '';
47
        while ($file->key() < $method->getEndLine()) {
48
            $code .= $file->current();
49
            $file->next();
50
        }
51
52
        $code = trim(preg_replace('/\s\s+/', '', $code));
53
        $begin = strpos($code, 'function(');
54
        $code = substr($code, $begin, strrpos($code, '}') - $begin + 1);
55
        $lastCode = $code[strlen($code) - 1];
0 ignored issues
show
Unused Code introduced by
The assignment to $lastCode is dead and can be removed.
Loading history...
56
57
        return $code;
58
    }
59
    /**
60
     * @param  Model $model
61
     * @return array
62
     */
63
    protected function getModelClassMethods(Model $model)
64
    {
65
        // TODO: Handle case when Mock::class not present
66
        return array_diff(
67
            get_class_methods($model),
68
            get_class_methods(\Illuminate\Database\Eloquent\Model::class),
69
            get_class_methods(Mock::class),
70
            get_class_methods(MetadataTrait::class)
71
        );
72
    }
73
    /**
74
     * @param bool $biDir
75
     *
76
     * @throws InvalidOperationException
77
     * @throws \ReflectionException
78
     * @return array
79
     */
80
    protected function getRelationshipsFromMethods()
81
    {
82
        /*$biDirVal = true;
83
        $isCached = isset(static::$relationCategories[$biDirVal]) && !empty(static::$relationCategories[$biDirVal]);
84
        if ($isCached) {
85
            return static::$relationCategories[$biDirVal];
86
        }*/
87
        $relationships = [];
88
        /** @var Model $model */
89
        $model = $this;
90
        $methods = $this->getModelClassMethods($model);
91
        foreach ($methods as $method) {
92
            //Use reflection to inspect the code, based on Illuminate/Support/SerializableClosure.php
93
            $reflection = new \ReflectionMethod($model, $method);
94
            $code = $this->getCodeForMethod($reflection);
95
            foreach (static::$relTypes as $relation) {
96
                //Resolve the relation's model to a Relation object.
97
                if (
98
                    !stripos($code, sprintf('$this->%s(', $relation)) ||
99
                    !(($relationObj = $model->$method()) instanceof Relation) ||
100
                    !in_array(MetadataTrait::class, class_uses($relationObj->getRelated()))
101
                ) {
102
                    continue;
103
                }
104
                $relationships[]= $method;
105
            }
106
        }
107
        return $relationships;
108
    }
109
}
110