1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Codeburner Framework. |
5
|
|
|
* |
6
|
|
|
* @author Alex Rohleder <[email protected]> |
7
|
|
|
* @copyright 2016 Alex Rohleder |
8
|
|
|
* @license http://opensource.org/licenses/MIT |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace Codeburner\Router; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* Representation of a group of several routes with same |
15
|
|
|
* controller and respecting the resourceful actions. |
16
|
|
|
* |
17
|
|
|
* @author Alex Rohleder <[email protected]> |
18
|
|
|
*/ |
19
|
|
|
|
20
|
|
|
class Resource extends Group |
21
|
|
|
{ |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @inheritdoc |
25
|
|
|
* @throws \BadMethodCallException |
26
|
|
|
*/ |
27
|
|
|
|
28
|
|
|
public function setMethod($method) |
29
|
|
|
{ |
30
|
|
|
throw new \BadMethodCallException("Resources can't chance they http method."); |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Remove the routes without the passed methods. |
35
|
|
|
* |
36
|
|
|
* @param string|array $methods |
37
|
|
|
* @return self |
38
|
|
|
*/ |
39
|
|
|
|
40
|
|
|
public function only($methods) |
41
|
|
|
{ |
42
|
|
|
$this->filterByMethod((array) $methods, false); |
43
|
|
|
return $this; |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Remove the routes with the passed methods. |
48
|
|
|
* |
49
|
|
|
* @param string|array $methods |
50
|
|
|
* @return self |
51
|
|
|
*/ |
52
|
|
|
|
53
|
|
|
public function except($methods) |
54
|
|
|
{ |
55
|
|
|
$this->filterByMethod((array) $methods, true); |
56
|
|
|
return $this; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Forget the grouped routes filtering by http methods. |
61
|
|
|
* |
62
|
|
|
* @param array $methods |
63
|
|
|
* @param bool $alt Should remove? |
64
|
|
|
*/ |
65
|
|
|
|
66
|
|
|
private function filterByMethod(array $methods, $alt) |
67
|
|
|
{ |
68
|
|
|
$methods = array_flip(array_map('strtolower', $methods)); |
69
|
|
|
|
70
|
|
|
foreach ($this->routes as $route) { |
71
|
|
|
if (isset($methods[$route->getAction()[1]]) === $alt) { |
72
|
|
|
$route->forget(); |
73
|
|
|
} |
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Translate the "make" or "edit" from resources path. |
79
|
|
|
* |
80
|
|
|
* @param string[] $translations |
81
|
|
|
* @return self |
82
|
|
|
*/ |
83
|
|
|
|
84
|
|
|
public function translate(array $translations) |
85
|
|
|
{ |
86
|
|
|
/** @var Route $route */ |
87
|
|
|
foreach ($this->route as $route) { |
|
|
|
|
88
|
|
|
$action = $route->getAction()[1]; |
89
|
|
|
|
90
|
|
|
if ($action === "make" && isset($translations["make"])) { |
91
|
|
|
$route->setPatternWithoutReset(str_replace("make", $translations["make"], $route->getPattern())); |
92
|
|
|
} else { |
93
|
|
|
if ($action === "edit" && isset($translations["edit"])) { |
94
|
|
|
$route->setPatternWithoutReset(str_replace("edit", $translations["edit"], $route->getPattern())); |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
return $this; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Add a route or a group of routes to the resource, it means that |
104
|
|
|
* every added route will now receive the parameters of the resource, like id. |
105
|
|
|
* |
106
|
|
|
* @param Route|Group $route |
107
|
|
|
* @return self |
108
|
|
|
*/ |
109
|
|
|
|
110
|
|
|
public function member($route) |
111
|
|
|
{ |
112
|
|
|
$resource = new Resource; |
113
|
|
|
$resource->set($route); |
114
|
|
|
$this->nest($resource); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* Nested routes capture the relation between a resource and another resource. |
119
|
|
|
* |
120
|
|
|
* @param Resource $resource |
121
|
|
|
* @return self |
122
|
|
|
*/ |
123
|
|
|
|
124
|
|
|
public function nest(Resource $resource) |
125
|
|
|
{ |
126
|
|
|
/** @var self $resource */ |
127
|
|
|
foreach ($this->routes as $route) { |
128
|
|
|
if ($route->getAction()[1] === "show") { |
129
|
|
|
$this->set($resource->forget()->setPrefix($this->getNestedPrefix($route->getPattern()))); break; |
130
|
|
|
} |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
return $this; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* Nest resources but with only build routes with the minimal amount of information |
138
|
|
|
* to uniquely identify the resource. |
139
|
|
|
* |
140
|
|
|
* @param Resource $resource |
141
|
|
|
* @return self |
142
|
|
|
*/ |
143
|
|
|
|
144
|
|
|
public function shallow(Resource $resource) |
145
|
|
|
{ |
146
|
|
|
/** @var self $resource */ |
147
|
|
|
$newResource = new Resource; |
148
|
|
|
$resource->forget(); |
149
|
|
|
$routes = $resource->all(); |
150
|
|
|
|
151
|
|
|
foreach ($routes as $route) { |
152
|
|
|
if (strpos("index make create", $route->getAction()[1]) !== false) { |
153
|
|
|
$newResource->set($route); |
154
|
|
|
} |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
return $this->nest($newResource); |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* Resolve the nesting pattern, setting the prefixes based on |
162
|
|
|
* parent resources patterns. |
163
|
|
|
* |
164
|
|
|
* @param string $pattern |
165
|
|
|
* @return string |
166
|
|
|
*/ |
167
|
|
|
|
168
|
|
|
protected function getNestedPrefix($pattern) |
169
|
|
|
{ |
170
|
|
|
$segments = explode("/", $pattern); |
171
|
|
|
$pattern = ""; |
172
|
|
|
|
173
|
|
|
foreach ($segments as $index => $segment) { |
174
|
|
|
if (strpos($segment, "{") === 0) { |
175
|
|
|
$pattern .= "/{" . $segments[$index - 1] . "_" . ltrim($segment, "{"); |
176
|
|
|
} else $pattern .= $segment; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
return $pattern; |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
} |
183
|
|
|
|
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.