Passed
Pull Request — master (#201)
by Alex
06:01
created

polyglotThroughKeyMethodNames()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 7
rs 10
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: alex
5
 * Date: 13/02/20
6
 * Time: 4:22 AM
7
 */
8
9
namespace AlgoWeb\PODataLaravel\Models;
10
11
use Illuminate\Database\Eloquent\Model;
12
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
13
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
14
use Illuminate\Database\Eloquent\Relations\Relation;
15
use POData\Common\InvalidOperationException;
16
17
trait MetadataKeyMethodNamesTrait
18
{
19
    protected static $methodAlternate = [];
20
    protected static $methodPrimary = [];
21
22
    /**
23
     * @param Relation $foo
24
     * @return array|null
25
     * @throws InvalidOperationException
26
     */
27
    protected function getRelationsHasManyKeyNames($foo)
28
    {
29
        $thruName = null;
30
        if ($foo instanceof HasManyThrough) {
31
            list($fkMethodName, $rkMethodName) = $this->polyglotKeyMethodBackupNames($foo, true);
32
            $thruName = $this->polyglotThroughKeyMethodNames($foo);
33
            return [$thruName, $fkMethodName, $rkMethodName];
34
        }
35
        if ($foo instanceof BelongsToMany) {
36
            list($fkMethodName, $rkMethodName) = $this->polyglotKeyMethodNames($foo, true);
37
            return [$thruName, $fkMethodName, $rkMethodName];
38
        }
39
        list($fkMethodName, $rkMethodName) = $this->polyglotKeyMethodBackupNames($foo, true);
40
        return [$thruName, $fkMethodName, $rkMethodName];
41
    }
42
43
    /**
44
     * @param       $foo
45
     * @param mixed $condition
46
     *
47
     * @return array
48
     * @throws InvalidOperationException
49
     */
50
    protected function polyglotKeyMethodNames($foo, $condition = false)
51
    {
52
        // if $condition is falsy, return quickly - don't muck around
53
        if (!$condition) {
54
            return [null, null];
55
        }
56
57
        $fkList = ['getQualifiedForeignKeyName', 'getForeignKey'];
58
        $rkList = ['getQualifiedRelatedKeyName', 'getOtherKey', 'getOwnerKey', 'getQualifiedOwnerKeyName'];
59
60
        $fkMethodName = null;
61
        $rkMethodName = null;
62
63
        if (array_key_exists(get_class($foo), static::$methodPrimary)) {
64
            $line = static::$methodPrimary[get_class($foo)];
65
            $fkMethodName = $line['fk'];
66
            $rkMethodName = $line['rk'];
67
        } else {
68
            $methodList = get_class_methods(get_class($foo));
69
            $fkMethodName = 'getQualifiedForeignPivotKeyName';
70
            $fkIntersect = array_values(array_intersect($fkList, $methodList));
71
            $fkMethodName = (0 < count($fkIntersect)) ? $fkIntersect[0] : $fkMethodName;
72
            if (!(in_array($fkMethodName, $methodList))) {
73
                $msg = 'Selected method, ' . $fkMethodName . ', not in method list';
74
                throw new InvalidOperationException($msg);
75
            }
76
            $rkMethodName = 'getQualifiedRelatedPivotKeyName';
77
            $rkIntersect = array_values(array_intersect($rkList, $methodList));
78
            $rkMethodName = (0 < count($rkIntersect)) ? $rkIntersect[0] : $rkMethodName;
79
            if (!(in_array($rkMethodName, $methodList))) {
80
                $msg = 'Selected method, ' . $rkMethodName . ', not in method list';
81
                throw new InvalidOperationException($msg);
82
            }
83
            $line = ['fk' => $fkMethodName, 'rk' => $rkMethodName];
84
            static::$methodPrimary[get_class($foo)] = $line;
85
        }
86
        return [$fkMethodName, $rkMethodName];
87
    }
88
89
    /**
90
     * @param Model|Relation $foo
91
     * @param bool $condition
92
     * @return array
93
     * @throws InvalidOperationException
94
     */
95
    protected function polyglotKeyMethodBackupNames($foo, $condition = false)
96
    {
97
        // if $condition is falsy, return quickly - don't muck around
98
        if (!$condition) {
99
            return [null, null];
100
        }
101
102
        $fkList = ['getForeignKey', 'getForeignKeyName', 'getQualifiedFarKeyName'];
103
        $rkList = ['getOtherKey', 'getQualifiedParentKeyName'];
104
105
        $fkMethodName = null;
106
        $rkMethodName = null;
107
108
        if (array_key_exists(get_class($foo), static::$methodAlternate)) {
109
            $line = static::$methodAlternate[get_class($foo)];
110
            $fkMethodName = $line['fk'];
111
            $rkMethodName = $line['rk'];
112
        } else {
113
            $methodList = get_class_methods(get_class($foo));
114
            $fkCombo = array_values(array_intersect($fkList, $methodList));
115
            if (!(1 <= count($fkCombo))) {
116
                $msg = 'Expected at least 1 element in foreign-key list, got ' . count($fkCombo);
117
                throw new InvalidOperationException($msg);
118
            }
119
            $fkMethodName = $fkCombo[0];
120
            if (!(in_array($fkMethodName, $methodList))) {
121
                $msg = 'Selected method, ' . $fkMethodName . ', not in method list';
122
                throw new InvalidOperationException($msg);
123
            }
124
            $rkCombo = array_values(array_intersect($rkList, $methodList));
125
            if (!(1 <= count($rkCombo))) {
126
                $msg = 'Expected at least 1 element in related-key list, got ' . count($rkCombo);
127
                throw new InvalidOperationException($msg);
128
            }
129
            $rkMethodName = $rkCombo[0];
130
            if (!(in_array($rkMethodName, $methodList))) {
131
                $msg = 'Selected method, ' . $rkMethodName . ', not in method list';
132
                throw new InvalidOperationException($msg);
133
            }
134
            $line = ['fk' => $fkMethodName, 'rk' => $rkMethodName];
135
            static::$methodAlternate[get_class($foo)] = $line;
136
        }
137
        return [$fkMethodName, $rkMethodName];
138
    }
139
140
    protected function polyglotThroughKeyMethodNames(HasManyThrough $foo)
141
    {
142
        $thruList = ['getThroughKey', 'getQualifiedFirstKeyName'];
143
144
        $methodList = get_class_methods(get_class($foo));
145
        $thruCombo = array_values(array_intersect($thruList, $methodList));
146
        return $thruCombo[0];
147
    }
148
}
149