Completed
Pull Request — master (#219)
by Christopher
06:20
created

MetadataKeyMethodNamesTrait::polyglotFkKey()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 15
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 13
c 0
b 0
f 0
dl 0
loc 15
rs 9.5222
cc 5
nc 5
nop 1
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: alex
5
 * Date: 13/02/20
6
 * Time: 4:22 AM.
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\BelongsToMany;
13
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
14
use Illuminate\Database\Eloquent\Relations\HasOneOrMany;
15
use Illuminate\Database\Eloquent\Relations\Relation;
16
use Mockery\Mock;
17
use POData\Common\InvalidOperationException;
18
19
trait MetadataKeyMethodNamesTrait
20
{
21
    /**
22
     * @param Relation $foo
23
     * @param mixed    $condition
24
     *
25
     * @throws InvalidOperationException
26
     * @return array
27
     */
28
    protected function polyglotKeyMethodNames(Relation $foo)
29
    {
30
        if ($foo instanceof BelongsTo) {
31
            // getForeignKey for laravel 5.5
32
            $fkList = ['getForeignKeyName', 'getForeignKey'];
33
            // getOwnerKeyName for laravel 5.5
34
            $rkList = ['getOwnerKey', 'getOwnerKeyName'];
35
        }elseif ($foo instanceof BelongsToMany) {
36
            $fkList = ['getForeignPivotKeyName'];
37
            $rkList = ['getRelatedPivotKeyName'];
38
        }elseif($foo instanceof HasOneOrMany){
39
            $fkList = ['getForeignKeyName'];
40
            $rkList = ['getLocalKeyName', 'getQualifiedParentKeyName'];
41
        }elseif($foo instanceof HasManyThrough) {
42
            $fkList = ['getQualifiedFarKeyName'];
43
            $rkList = ['getQualifiedParentKeyName'];
44
        }else{
45
            $msg = sprintf('Unknown Relationship Type %s', get_class($foo));
46
            throw new InvalidOperationException($msg);
47
        }
48
        $fkMethodName = $this->checkMethodNameList($foo, $fkList);
49
50
        $rkMethodName = $this->checkMethodNameList($foo, $rkList);
51
52
        return [$fkMethodName, $rkMethodName];
53
    }
54
    protected function polyglotFkKey(Relation $rel)
55
    {
56
        switch (true) {
57
            case $rel instanceof BelongsTo:
58
                return $rel->{$this->checkMethodNameList($rel, ['getForeignKeyName', 'getForeignKey'])}();
59
            case $rel instanceof BelongsToMany:
60
                return $rel->getForeignPivotKeyName();
61
            case $rel instanceof HasOneOrMany:
62
                return $rel->getForeignKeyName();
63
            case $rel instanceof HasManyThrough:
64
                $segments = explode('.', $rel->getQualifiedFarKeyName());
65
                return end($segments);
66
            default:
67
                $msg = sprintf('Unknown Relationship Type %s', get_class($rel));
68
                throw new InvalidOperationException($msg);
69
        }
70
    }
71
    protected function polyglotRkKey(Relation $rel)
72
    {
73
        switch (true) {
74
            case $rel instanceof BelongsTo:
75
                return $rel->{$this->checkMethodNameList($rel, ['getOwnerKey', 'getOwnerKeyName'])}();
76
            case $rel instanceof BelongsToMany:
77
                return $rel->getRelatedPivotKeyName();
78
            case $rel instanceof HasOneOrMany:
79
                $segments = explode('.', $rel->{$this->checkMethodNameList($rel, ['getLocalKeyName', 'getQualifiedParentKeyName'])}());
80
                return end($segments);
81
            case $rel instanceof HasManyThrough:
82
                $segments = explode('.', $rel->getQualifiedParentKeyName());
83
                return end($segments);
84
            default:
85
                $msg = sprintf('Unknown Relationship Type %s', get_class($rel));
86
                throw new InvalidOperationException($msg);
87
        }
88
    }
89
90
    protected function polyglotThroughKey(Relation $rel){
91
        if(! $rel instanceof HasManyThrough){
92
            return null;
93
        }
94
        $segments = explode('.', $rel->{$this->checkMethodNameList($rel, ['getThroughKey', 'getQualifiedFirstKeyName'])}());
95
        return end($segments);
96
    }
97
98
    /**
99
     * @param  HasManyThrough            $foo
100
     * @throws InvalidOperationException
101
     * @return string
102
     */
103
    protected function polyglotThroughKeyMethodNames(HasManyThrough $foo)
104
    {
105
        $thruList = ['getThroughKey', 'getQualifiedFirstKeyName'];
106
107
        return $this->checkMethodNameList($foo, $thruList);
108
    }
109
110
    /**
111
     * @param  Model $model
112
     * @return array
113
     */
114
    protected function getModelClassMethods(Model $model)
115
    {
116
        return array_diff(
117
            get_class_methods($model),
118
            get_class_methods(\Illuminate\Database\Eloquent\Model::class),
119
            //TODO: sandi what will happen if Mock is not installed (I.e. Production?)
120
            get_class_methods(Mock::class),
121
            get_class_methods(MetadataTrait::class)
122
        );
123
    }
124
125
    /**
126
     * @param  Relation                  $foo
127
     * @param  array                     $methodList
128
     * @throws InvalidOperationException
129
     * @return string
130
     */
131
    protected function checkMethodNameList(Relation $foo, array $methodList)
132
    {
133
        foreach ($methodList as $methodName) {
134
            if (method_exists($foo, $methodName)) {
135
                return $methodName;
136
            }
137
        }
138
        $msg = 'Expected at least 1 element in related-key list, got 0 for relation %s';
139
        throw new InvalidOperationException(sprintf($msg,get_class($foo)));
140
    }
141
}
142