1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace AlgoWeb\PODataLaravel\Controllers; |
4
|
|
|
|
5
|
|
|
use Illuminate\Routing\Controller as BaseController; |
6
|
|
|
|
7
|
|
|
trait MetadataControllerTrait |
8
|
|
|
{ |
9
|
|
|
/* |
10
|
|
|
* Allowed crud verbs |
11
|
|
|
*/ |
12
|
|
|
protected $crudVerbs = ['create', 'read', 'update', 'delete']; |
13
|
|
|
|
14
|
|
|
/* |
15
|
|
|
* Array to record mapping betweeen model-verb combos and names |
16
|
|
|
* First-level key is fully-qualified model name |
17
|
|
|
* (eg Alt\Swedish\Chef\Bork\Bork\Bork) |
18
|
|
|
* Second-level key is CRUD verb |
19
|
|
|
*/ |
20
|
|
|
protected $mapping; |
21
|
|
|
|
22
|
|
|
/* |
23
|
|
|
* Given model and verb, get method name and parameter list |
24
|
|
|
* |
25
|
|
|
* @param $modelName |
26
|
|
|
* @param $crudVerb |
27
|
|
|
* @return array |
28
|
|
|
* @throws \Exception |
29
|
|
|
*/ |
30
|
9 |
|
public function getMethodName($modelName, $crudVerb) |
31
|
|
|
{ |
32
|
|
|
// enforce we're actually hooked up to a controller |
33
|
9 |
|
assert($this instanceof BaseController, get_class($this)); |
34
|
|
|
// enforce that mapping is actually not empty |
35
|
9 |
|
assert(0 < count($this->mapping), "Mapping array must not be empty"); |
|
|
|
|
36
|
|
|
|
37
|
8 |
|
if (!array_key_exists($modelName, $this->mapping)) { |
38
|
1 |
|
throw new \Exception('Metadata mapping for model '.$modelName.' not defined'); |
39
|
|
|
} |
40
|
|
|
|
41
|
7 |
|
if (!in_array(strtolower($crudVerb), $this->crudVerbs)) { |
|
|
|
|
42
|
1 |
|
throw new \Exception('CRUD verb '.$crudVerb.' not defined'); |
43
|
|
|
} |
44
|
|
|
|
45
|
6 |
|
$lookup = $this->mapping[$modelName]; |
46
|
6 |
|
if (!is_array($lookup)) { |
47
|
1 |
|
throw new \Exception('Metadata mapping for model '.$modelName.' not an array'); |
48
|
|
|
} |
49
|
|
|
|
50
|
5 |
|
if (!array_key_exists($crudVerb, $lookup)) { |
51
|
1 |
|
throw new \Exception('Metadata mapping for CRUD verb '.$crudVerb.' on model '.$modelName.' not defined'); |
52
|
|
|
} |
53
|
4 |
|
$result = $lookup[$crudVerb]; |
54
|
4 |
View Code Duplication |
if (!isset($result)) { |
|
|
|
|
55
|
1 |
|
throw new \Exception('Metadata mapping for CRUD verb '.$crudVerb.' on model '.$modelName.' null'); |
56
|
|
|
} |
57
|
|
|
|
58
|
3 |
View Code Duplication |
if (!method_exists($this, $result)) { |
|
|
|
|
59
|
1 |
|
throw new \Exception( |
60
|
1 |
|
'Metadata target for CRUD verb '.$crudVerb.' on model '.$modelName.' does not exist' |
61
|
1 |
|
); |
62
|
|
|
} |
63
|
|
|
|
64
|
2 |
|
$class = get_class($this); |
65
|
2 |
|
$parmArray = $this->getParameterNames($result); |
66
|
|
|
|
67
|
2 |
|
return ['method' => $result, 'controller' => $class, 'parameters' => $parmArray]; |
68
|
|
|
} |
69
|
|
|
|
70
|
68 |
|
public function getMappings() |
71
|
|
|
{ |
72
|
|
|
// enforce we're actually hooked up to a controller |
73
|
68 |
|
assert($this instanceof BaseController, get_class($this)); |
74
|
|
|
// enforce that mapping is actually not empty |
75
|
68 |
|
assert(!empty($this->mapping), "Mapping array must not be empty"); |
|
|
|
|
76
|
|
|
|
77
|
68 |
|
$allMappings = []; |
78
|
|
|
|
79
|
|
|
// check that mapping array is well formed and sane, rather than waiting to stab us with a spatula |
80
|
68 |
|
foreach ($this->mapping as $key => $map) { |
81
|
68 |
|
if (!is_array($map)) { |
82
|
1 |
|
throw new \Exception('Metadata mapping for model '.$key.' not an array'); |
83
|
|
|
} |
84
|
68 |
|
foreach ($map as $verb => $method) { |
85
|
68 |
|
if (!in_array(strtolower($verb), $this->crudVerbs)) { |
|
|
|
|
86
|
1 |
|
throw new \Exception('CRUD verb '.$verb.' not defined'); |
87
|
|
|
} |
88
|
68 |
|
if (!isset($method)) { |
89
|
1 |
|
throw new \Exception('Metadata mapping for CRUD verb '.$verb.' on model '.$key.' null'); |
90
|
|
|
} |
91
|
|
|
|
92
|
68 |
|
if (!method_exists($this, $method)) { |
93
|
1 |
|
throw new \Exception( |
94
|
1 |
|
'Metadata target for CRUD verb '.$verb.' on model '.$key.' does not exist' |
95
|
1 |
|
); |
96
|
|
|
} |
97
|
68 |
|
$parmArray = $this->getParameterNames($method); |
98
|
68 |
|
if (!array_key_exists($key, $allMappings)) { |
99
|
68 |
|
$allMappings[$key] = []; |
100
|
68 |
|
} |
101
|
|
|
|
102
|
68 |
|
$class = get_class($this); |
103
|
68 |
|
$allMappings[$key][$verb] = ['method' => $method, 'controller' => $class, 'parameters' => $parmArray]; |
104
|
68 |
|
} |
105
|
68 |
|
} |
106
|
68 |
|
return $allMappings; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* @param $result |
111
|
|
|
* @return array |
112
|
|
|
*/ |
113
|
68 |
|
protected function getParameterNames($result) |
114
|
|
|
{ |
115
|
68 |
|
$parmArray = []; |
116
|
68 |
|
$r = new \ReflectionMethod($this, $result); |
117
|
68 |
|
$params = $r->getParameters(); |
118
|
68 |
|
foreach ($params as $parm) { |
119
|
68 |
|
$detail = []; |
120
|
68 |
|
$detail['name'] = $parm->name; |
121
|
68 |
|
$classHint = $parm->getClass(); |
122
|
68 |
|
$isRequest = false; |
123
|
68 |
|
if (null != $classHint) { |
124
|
|
|
// check to see if this is a request |
125
|
68 |
|
$className = $classHint->name; |
126
|
68 |
|
$class = new $className(); |
127
|
68 |
|
$isRequest = $class instanceof \Illuminate\Http\Request; |
128
|
68 |
|
$detail['type'] = $className; |
129
|
68 |
|
} |
130
|
|
|
|
131
|
68 |
|
$detail['isRequest'] = $isRequest; |
132
|
68 |
|
$parmArray[$parm->name] = $detail; |
133
|
|
|
} |
134
|
68 |
|
return $parmArray; |
135
|
68 |
|
} |
136
|
|
|
} |
137
|
|
|
|
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.
If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.