Passed
Pull Request — master (#201)
by Alex
06:08
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
20
    protected static $methodAlternate = [];
21
    protected static $methodPrimary = [];
22
23
    /**
24
     * @param Relation $foo
25
     * @return array|null
26
     * @throws InvalidOperationException
27
     */
28
    protected function getRelationsHasManyKeyNames($foo)
29
    {
30
        $thruName = null;
31
        if ($foo instanceof HasManyThrough) {
32
            list($fkMethodName, $rkMethodName) = $this->polyglotKeyMethodBackupNames($foo, true);
33
            $thruName = $this->polyglotThroughKeyMethodNames($foo);
34
            return [$thruName, $fkMethodName, $rkMethodName];
35
        }
36
        if ($foo instanceof BelongsToMany) {
37
            list($fkMethodName, $rkMethodName) = $this->polyglotKeyMethodNames($foo, true);
38
            return [$thruName, $fkMethodName, $rkMethodName];
39
        }
40
        list($fkMethodName, $rkMethodName) = $this->polyglotKeyMethodBackupNames($foo, true);
41
        return [$thruName, $fkMethodName, $rkMethodName];
42
    }
43
44
    /**
45
     * @param       $foo
46
     * @param mixed $condition
47
     *
48
     * @return array
49
     * @throws InvalidOperationException
50
     */
51
    protected function polyglotKeyMethodNames($foo, $condition = false)
52
    {
53
        // if $condition is falsy, return quickly - don't muck around
54
        if (!$condition) {
55
            return [null, null];
56
        }
57
58
        $fkList = ['getQualifiedForeignKeyName', 'getForeignKey'];
59
        $rkList = ['getQualifiedRelatedKeyName', 'getOtherKey', 'getOwnerKey', 'getQualifiedOwnerKeyName'];
60
61
        $fkMethodName = null;
62
        $rkMethodName = null;
63
64
        if (array_key_exists(get_class($foo), static::$methodPrimary)) {
65
            $line = static::$methodPrimary[get_class($foo)];
66
            $fkMethodName = $line['fk'];
67
            $rkMethodName = $line['rk'];
68
        } else {
69
            $methodList = get_class_methods(get_class($foo));
70
            $fkMethodName = 'getQualifiedForeignPivotKeyName';
71
            $fkIntersect = array_values(array_intersect($fkList, $methodList));
72
            $fkMethodName = (0 < count($fkIntersect)) ? $fkIntersect[0] : $fkMethodName;
73
            if (!(in_array($fkMethodName, $methodList))) {
74
                $msg = 'Selected method, ' . $fkMethodName . ', not in method list';
75
                throw new InvalidOperationException($msg);
76
            }
77
            $rkMethodName = 'getQualifiedRelatedPivotKeyName';
78
            $rkIntersect = array_values(array_intersect($rkList, $methodList));
79
            $rkMethodName = (0 < count($rkIntersect)) ? $rkIntersect[0] : $rkMethodName;
80
            if (!(in_array($rkMethodName, $methodList))) {
81
                $msg = 'Selected method, ' . $rkMethodName . ', not in method list';
82
                throw new InvalidOperationException($msg);
83
            }
84
            $line = ['fk' => $fkMethodName, 'rk' => $rkMethodName];
85
            static::$methodPrimary[get_class($foo)] = $line;
86
        }
87
        return [$fkMethodName, $rkMethodName];
88
    }
89
90
    /**
91
     * @param Model|Relation $foo
92
     * @param bool $condition
93
     * @return array
94
     * @throws InvalidOperationException
95
     */
96
    protected function polyglotKeyMethodBackupNames($foo, $condition = false)
97
    {
98
        // if $condition is falsy, return quickly - don't muck around
99
        if (!$condition) {
100
            return [null, null];
101
        }
102
103
        $fkList = ['getForeignKey', 'getForeignKeyName', 'getQualifiedFarKeyName'];
104
        $rkList = ['getOtherKey', 'getQualifiedParentKeyName'];
105
106
        $fkMethodName = null;
107
        $rkMethodName = null;
108
109
        if (array_key_exists(get_class($foo), static::$methodAlternate)) {
110
            $line = static::$methodAlternate[get_class($foo)];
111
            $fkMethodName = $line['fk'];
112
            $rkMethodName = $line['rk'];
113
        } else {
114
            $methodList = get_class_methods(get_class($foo));
115
            $fkCombo = array_values(array_intersect($fkList, $methodList));
116
            if (!(1 <= count($fkCombo))) {
117
                $msg = 'Expected at least 1 element in foreign-key list, got ' . count($fkCombo);
118
                throw new InvalidOperationException($msg);
119
            }
120
            $fkMethodName = $fkCombo[0];
121
            if (!(in_array($fkMethodName, $methodList))) {
122
                $msg = 'Selected method, ' . $fkMethodName . ', not in method list';
123
                throw new InvalidOperationException($msg);
124
            }
125
            $rkCombo = array_values(array_intersect($rkList, $methodList));
126
            if (!(1 <= count($rkCombo))) {
127
                $msg = 'Expected at least 1 element in related-key list, got ' . count($rkCombo);
128
                throw new InvalidOperationException($msg);
129
            }
130
            $rkMethodName = $rkCombo[0];
131
            if (!(in_array($rkMethodName, $methodList))) {
132
                $msg = 'Selected method, ' . $rkMethodName . ', not in method list';
133
                throw new InvalidOperationException($msg);
134
            }
135
            $line = ['fk' => $fkMethodName, 'rk' => $rkMethodName];
136
            static::$methodAlternate[get_class($foo)] = $line;
137
        }
138
        return [$fkMethodName, $rkMethodName];
139
    }
140
141
    protected function polyglotThroughKeyMethodNames(HasManyThrough $foo)
142
    {
143
        $thruList = ['getThroughKey', 'getQualifiedFirstKeyName'];
144
145
        $methodList = get_class_methods(get_class($foo));
146
        $thruCombo = array_values(array_intersect($thruList, $methodList));
147
        return $thruCombo[0];
148
    }
149
}