1: <?php
2:
3: namespace Charcoal\App\Route;
4:
5:
6: use Psr\Http\Message\RequestInterface;
7: use Psr\Http\Message\ResponseInterface;
8:
9:
10: use Charcoal\Config\ConfigurableInterface;
11: use Charcoal\Config\ConfigurableTrait;
12:
13:
14: use Charcoal\App\AppAwareInterface;
15: use Charcoal\App\AppAwareTrait;
16: use Charcoal\App\Route\ActionRoute;
17: use Charcoal\App\Route\ScriptRoute;
18: use Charcoal\App\Route\TemplateRoute;
19:
20: 21: 22:
23: class RouteManager implements
24: AppAwareInterface,
25: ConfigurableInterface
26: {
27: use AppAwareTrait;
28: use ConfigurableTrait;
29:
30: 31: 32: 33: 34:
35: private $routeData = [];
36:
37: 38: 39: 40: 41:
42: public function __construct(array $data)
43: {
44: $this->setConfig($data['config']);
45: $this->setApp($data['app']);
46: }
47:
48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58:
59: public function setupRoutes()
60: {
61: $routes = $this->config();
62:
63: if (PHP_SAPI == 'cli') {
64: $scripts = ( isset($routes['scripts']) ? $routes['scripts'] : [] );
65: foreach ($scripts as $scriptIdent => $scriptConfig) {
66: $this->setupScript($scriptIdent, $scriptConfig);
67: }
68: } else {
69: $templates = ( isset($routes['templates']) ? $routes['templates'] : [] );
70: foreach ($templates as $routeIdent => $templateConfig) {
71: $this->setupTemplate($routeIdent, $templateConfig);
72: }
73:
74: $actions = ( isset($routes['actions']) ? $routes['actions'] : [] );
75: foreach ($actions as $actionIdent => $actionConfig) {
76: $this->setupAction($actionIdent, $actionConfig);
77: }
78: }
79: }
80:
81: 82: 83: 84: 85: 86: 87: 88: 89:
90: private function setupTemplate($routeIdent, $templateConfig)
91: {
92: $routePattern = isset($templateConfig['route'])
93: ? $templateConfig['route']
94: : '/'.ltrim($routeIdent, '/');
95:
96: $templateConfig['route'] = $routePattern;
97:
98: $methods = isset($templateConfig['methods'])
99: ? $templateConfig['methods']
100: : [ 'GET' ];
101:
102: $routeHandler = $this->app()->map(
103: $methods,
104: $routePattern,
105: function (
106: RequestInterface $request,
107: ResponseInterface $response,
108: array $args = []
109: ) use (
110: $routeIdent,
111: $templateConfig
112: ) {
113: if (!isset($templateConfig['ident'])) {
114: $templateConfig['ident'] = ltrim($routeIdent, '/');
115: }
116:
117: $this['logger']->debug(
118: sprintf('Loaded template route: %s', $templateConfig['ident']),
119: $templateConfig
120: );
121:
122: if (!isset($templateConfig['template_data'])) {
123: $templateConfig['template_data'] = [];
124: }
125:
126: if (count($args)) {
127: $templateConfig['template_data'] = array_merge(
128: $templateConfig['template_data'],
129: $args
130: );
131: }
132:
133: $defaultController = $this['route/controller/template/class'];
134: $routeController = isset($templateConfig['route_controller'])
135: ? $templateConfig['route_controller']
136: : $defaultController;
137:
138: $routeFactory = $this['route/factory'];
139: $routeFactory->setDefaultClass($defaultController);
140:
141: $route = $routeFactory->create($routeController, [
142: 'config' => $templateConfig,
143: 'logger' => $this['logger']
144: ]);
145:
146: return $route($this, $request, $response);
147: }
148: );
149:
150: if (isset($templateConfig['ident'])) {
151: $routeHandler->setName($templateConfig['ident']);
152: }
153:
154: return $routeHandler;
155: }
156:
157: 158: 159: 160: 161: 162: 163: 164: 165:
166: private function setupAction($routeIdent, $actionConfig)
167: {
168: $routePattern = isset($actionConfig['route'])
169: ? $actionConfig['route']
170: : '/'.ltrim($routeIdent, '/');
171:
172: $actionConfig['route'] = $routePattern;
173:
174: $methods = isset($actionConfig['methods'])
175: ? $actionConfig['methods']
176: : [ 'POST' ];
177:
178: $routeHandler = $this->app()->map(
179: $methods,
180: $routePattern,
181: function (
182: RequestInterface $request,
183: ResponseInterface $response,
184: array $args = []
185: ) use (
186: $routeIdent,
187: $actionConfig
188: ) {
189: if (!isset($actionConfig['ident'])) {
190: $actionConfig['ident'] = ltrim($routeIdent, '/');
191: }
192:
193: $this['logger']->debug(
194: sprintf('Loaded action route: %s', $actionConfig['ident']),
195: $actionConfig
196: );
197:
198: if (!isset($actionConfig['action_data'])) {
199: $actionConfig['action_data'] = [];
200: }
201:
202: if (count($args)) {
203: $actionConfig['action_data'] = array_merge(
204: $actionConfig['action_data'],
205: $args
206: );
207: }
208:
209: $defaultController = $this['route/controller/action/class'];
210: $routeController = isset($actionConfig['route_controller'])
211: ? $actionConfig['route_controller']
212: : $defaultController;
213:
214: $routeFactory = $this['route/factory'];
215: $routeFactory->setDefaultClass($defaultController);
216:
217: $route = $routeFactory->create($routeController, [
218: 'config' => $actionConfig,
219: 'logger' => $this['logger']
220: ]);
221:
222: return $route($this, $request, $response);
223: }
224: );
225:
226: if (isset($actionConfig['ident'])) {
227: $routeHandler->setName($actionConfig['ident']);
228: }
229:
230: return $routeHandler;
231: }
232:
233: 234: 235: 236: 237: 238: 239: 240: 241:
242: private function setupScript($routeIdent, $scriptConfig)
243: {
244: $routePattern = isset($scriptConfig['route'])
245: ? $scriptConfig['route']
246: : '/'.ltrim($routeIdent, '/');
247:
248: $scriptConfig['route'] = $routePattern;
249:
250: $methods = isset($scriptConfig['methods'])
251: ? $scriptConfig['methods']
252: : [ 'GET' ];
253:
254: $routeHandler = $this->app()->map(
255: $methods,
256: $routePattern,
257: function (
258: RequestInterface $request,
259: ResponseInterface $response,
260: array $args = []
261: ) use (
262: $routeIdent,
263: $scriptConfig
264: ) {
265: if (!isset($scriptConfig['ident'])) {
266: $scriptConfig['ident'] = ltrim($routeIdent, '/');
267: }
268:
269: $this['logger']->debug(
270: sprintf('Loaded script route: %s', $scriptConfig['ident']),
271: $scriptConfig
272: );
273:
274: if (!isset($scriptConfig['script_data'])) {
275: $scriptConfig['script_data'] = [];
276: }
277:
278: if (count($args)) {
279: $scriptConfig['script_data'] = array_merge(
280: $scriptConfig['script_data'],
281: $args
282: );
283: }
284:
285: $defaultController = $this['route/controller/script/class'];
286: $routeController = isset($scriptConfig['route_controller'])
287: ? $scriptConfig['route_controller']
288: : $defaultController;
289:
290: $routeFactory = $this['route/factory'];
291: $routeFactory->setDefaultClass($defaultController);
292:
293: $route = $routeFactory->create($routeController, [
294: 'config' => $scriptConfig,
295: 'logger' => $this['logger']
296: ]);
297:
298: return $route($this, $request, $response);
299: }
300: );
301:
302: if (isset($scriptConfig['ident'])) {
303: $routeHandler->setName($scriptConfig['ident']);
304: }
305:
306: return $routeHandler;
307: }
308: }
309: