Take the 2008 Git User's Survey and help out! [ hide ]

public
Description: Midgard Components Framework 3rd generation
Homepage: http://www.midgard-project.org
Clone URL: git://github.com/bergie/midcom.git
Search Repo:
Refactor WebDAV serving to dispatcher, and route matching to configuration
bergie (author)
Fri Jun 27 04:30:03 -0700 2008
commit  b3622d5782fbc3f32c5127bb2d02f3293b5ddfee
tree    9efcfada0853876af98ac31d36a340e7703eed25
parent  8f130e565970aefd518e0c69ac63302c8a7d5064
...
35
36
37
 
 
 
 
38
39
40
...
63
64
65
66
 
67
68
69
...
35
36
37
38
39
40
41
42
43
44
...
67
68
69
 
70
71
72
73
0
@@ -35,6 +35,10 @@ routes:
0
         controller: midcom_core_controllers_page
0
         action: show
0
         route: /
0
+ allowed_methods:
0
+ - OPTIONS
0
+ - GET
0
+ - PROPFIND
0
     page_edit:
0
         controller: midcom_core_controllers_page
0
         action: edit
0
@@ -63,7 +67,7 @@ routes:
0
     midcom_about:
0
         controller: midcom_core_controllers_about
0
         action: about
0
- route: /__midcom
0
+ route: /__midcom/@
0
         root_only: true
0
         content_entry_point: midcom-show-about
0
     comet_messages:
...
20
21
22
 
 
 
 
23
24
 
25
26
 
27
28
29
...
31
32
33
34
35
36
 
37
 
 
 
 
38
39
40
...
49
50
51
 
52
53
54
...
20
21
22
23
24
25
26
27
 
28
29
30
31
32
33
34
...
36
37
38
 
39
 
40
41
42
43
44
45
46
47
48
...
57
58
59
60
61
62
63
0
@@ -20,10 +20,15 @@ $_SERVER['PATH_INFO'] = $_MIDCOM->context->uri;
0
 class midcom_core_helpers_webdav extends HTTP_WebDAV_Server
0
 {
0
     private $logger = null;
0
+ private $controller = null;
0
+ private $route_id = '';
0
+ private $action_method = '';
0
+ private $action_arguments = array();
0
     
0
- public function __construct()
0
+ public function __construct($controller)
0
     {
0
         $this->logger = new midcom_core_helpers_log('webdav');
0
+ $this->controller = $controller;
0
         parent::HTTP_WebDAV_Server();
0
     }
0
 
0
@@ -31,10 +36,13 @@ class midcom_core_helpers_webdav extends HTTP_WebDAV_Server
0
      * Serve a WebDAV request
0
      *
0
      * @access public
0
- * @param string
0
      */
0
- public function serve($base = false)
0
+ public function serve($route_id, $action_method, $action_arguments)
0
     {
0
+ $this->route_id = $route_id;
0
+ $this->action_method = $action_method;
0
+ $this->action_arguments = $action_arguments;
0
+
0
         // special treatment for litmus compliance test
0
         // reply on its identifier header
0
         // not needed for the test itself but eases debugging
0
@@ -49,6 +57,7 @@ class midcom_core_helpers_webdav extends HTTP_WebDAV_Server
0
 
0
         $this->logger->log("\n\n=================================================", false);
0
         $this->logger->log("Serving {$_SERVER['REQUEST_METHOD']} request for {$_SERVER['REQUEST_URI']}");
0
+ $this->logger->log("Controller: " . get_class($this->controller) . ", action: {$this->action_method}");
0
         
0
         header("X-Dav-Method: {$_SERVER['REQUEST_METHOD']}");
0
         
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
...
212
213
214
215
216
217
218
219
220
221
222
223
...
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
...
243
244
245
246
 
 
 
 
 
 
247
248
249
...
173
174
175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
177
178
...
186
187
188
 
 
 
 
 
 
189
190
191
...
194
195
196
 
 
 
 
 
 
 
 
 
 
197
198
199
...
201
202
203
 
204
205
206
207
208
209
210
211
212
0
@@ -173,32 +173,6 @@ class midcom_core_midcom
0
         $_MIDCOM->templating->append_directory(MIDCOM_ROOT . '/midcom_core/templates');
0
         $this->dispatcher->populate_environment_data();
0
 
0
- switch ($_SERVER['REQUEST_METHOD'])
0
- {
0
- case 'GET':
0
- case 'POST':
0
- // GET and POST are handled by regular dispatcher
0
- $this->process_dispatcher();
0
- break;
0
- default:
0
- if ($this->configuration->get('enable_webdav'))
0
- {
0
- // Handle WebDAV methods
0
- $webdav_server = new midcom_core_helpers_webdav();
0
- $webdav_server->serve();
0
- // This will exit
0
- }
0
- break;
0
- }
0
-
0
- if ($this->timer)
0
- {
0
- $this->timer->setMarker('MidCOM::process ended');
0
- }
0
- }
0
-
0
- private function process_dispatcher()
0
- {
0
         // Load component
0
         try
0
         {
0
@@ -212,12 +186,6 @@ class midcom_core_midcom
0
         if (!$component)
0
         {
0
             $component = 'midcom_core';
0
- //if (!empty($this->dispatcher->argv))
0
- //{
0
- // FIXME: Process these also in the dispatcher as we will have some "core" routes
0
- // throw new midcom_exception_notfound("Page not found.");
0
- //}
0
- //return;
0
         }
0
         
0
         $this->dispatcher->initialize($component);
0
@@ -226,16 +194,6 @@ class midcom_core_midcom
0
         {
0
             $this->dispatcher->dispatch();
0
         }
0
- catch (midcom_exception_notfound $exception)
0
- {
0
- if ($this->configuration->get('enable_webdav'))
0
- {
0
- $webdav_server = new midcom_core_helpers_webdav();
0
- $webdav_server->serve();
0
- // This will exit
0
- }
0
- throw $exception;
0
- }
0
         catch (midcom_exception_unauthorized $exception)
0
         {
0
             // Pass the exception to authentication handler
0
@@ -243,6 +201,11 @@ class midcom_core_midcom
0
         }
0
 
0
         header('Content-Type: ' . $this->context->mimetype);
0
- }
0
+
0
+ if ($this->timer)
0
+ {
0
+ $this->timer->setMarker('MidCOM::process ended');
0
+ }
0
+ }
0
 }
0
 ?>
0
\ No newline at end of file
...
175
176
177
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
179
180
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
0
@@ -175,5 +175,117 @@ class midcom_core_services_configuration_yaml implements midcom_core_services_co
0
         // TODO: Implement using http://spyc.sourceforge.net/ if syck is not available
0
         return syck_dump($configuration);
0
     }
0
+
0
+ /**
0
+ * Normalizes routes configuration to include needed data
0
+ *
0
+ * @param array $route routes configuration
0
+ * @return array normalized routes configuration
0
+ */
0
+ public function normalize_routes($routes)
0
+ {
0
+ foreach ($routes as $identifier => $route)
0
+ {
0
+ // Handle the required route parameters
0
+ if (!isset($route['controller']))
0
+ {
0
+ throw Exception("Route {$identifier} has no controller defined");
0
+ }
0
+
0
+ if (!isset($route['action']))
0
+ {
0
+ throw Exception("Route {$identifier} has no action defined");
0
+ }
0
+
0
+ if (!isset($route['route']))
0
+ {
0
+ throw Exception("Route {$identifier} has no route path defined");
0
+ }
0
+
0
+ // Normalize additional parameters
0
+ if (!isset($route['allowed_methods']))
0
+ {
0
+ // Add default HTTP allowed methods
0
+ $route['allowed_methods'] = array
0
+ (
0
+ 'OPTIONS',
0
+ 'GET',
0
+ 'POST',
0
+ );
0
+ }
0
+
0
+ if (!isset($route['template_entry_point']))
0
+ {
0
+ // Add default HTTP allowed methods
0
+ $route['template_entry_point'] = 'ROOT';
0
+ }
0
+
0
+ if (!isset($route['content_entry_point']))
0
+ {
0
+ // Add default HTTP allowed methods
0
+ $route['content_entry_point'] = 'content';
0
+ }
0
+
0
+ $routes[$identifier] = $route;
0
+ }
0
+
0
+ return $routes;
0
+ }
0
+ /**
0
+ * Normalizes given route definition ready for parsing
0
+ *
0
+ * @param string $route route definition
0
+ * @return string normalized route
0
+ */
0
+ public function normalize_route_path($route)
0
+ {
0
+ // Normalize route
0
+ if ( strpos($route, '?') === false
0
+ && substr($route, -1, 1) !== '/')
0
+ {
0
+ $route .= '/';
0
+ }
0
+ return preg_replace('%/{2,}%', '/', $route);
0
+ }
0
+
0
+ /**
0
+ * Splits a given route (after normalizing it) to it's path and get parts
0
+ *
0
+ * @param string $route reference to a route definition
0
+ * @return array first item is path part, second is get part, both default to boolean false
0
+ */
0
+ public function split_route(&$route)
0
+ {
0
+ $route_path = false;
0
+ $route_get = false;
0
+ $route_args = false;
0
+
0
+ /* This will split route from "@" - mark
0
+ * /some/route/@somedata
0
+ * $matches[1] = /some/route/
0
+ * $matches[2] = somedata
0
+ */
0
+ preg_match('%([^@]*)@(.*)%', $route, $matches);
0
+
0
+ if(count($matches) > 0)
0
+ {
0
+ $route = $matches[1];
0
+ $route_args = explode('/', $matches[2]);
0
+ }
0
+
0
+ $route = $this->normalize_route_path($route);
0
+ // Get route parts
0
+ $route_parts = explode('?', $route, 2);
0
+ $route_path = $route_parts[0];
0
+ if (isset($route_parts[1]))
0
+ {
0
+ $route_get = $route_parts[1];
0
+ }
0
+ unset($route_parts);
0
+ return array($route_path, $route_get, $route_args);
0
+ }
0
+
0
+
0
+
0
 }
0
 ?>
0
\ No newline at end of file
...
166
167
168
169
 
170
171
172
...
174
175
176
177
 
178
179
180
181
 
182
183
184
...
217
218
219
 
 
 
 
 
 
 
220
221
222
223
224
225
 
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
228
229
...
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
...
377
378
379
380
 
381
382
383
...
419
420
421
422
423
 
 
 
 
 
 
 
 
 
 
424
425
426
...
483
484
485
486
487
 
 
 
 
 
 
 
 
 
 
488
489
490
...
166
167
168
 
169
170
171
172
...
174
175
176
 
177
178
179
180
181
182
183
184
185
...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
 
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
...
335
336
337
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
339
340
...
362
363
364
 
365
366
367
368
...
404
405
406
 
 
407
408
409
410
411
412
413
414
415
416
417
418
419
...
476
477
478
 
 
479
480
481
482
483
484
485
486
487
488
489
490
491
0
@@ -166,7 +166,7 @@ class midcom_core_services_dispatcher_midgard implements midcom_core_services_di
0
      */
0
     public function get_routes()
0
     {
0
- $this->core_routes = $_MIDCOM->configuration->get('routes');
0
+ $this->core_routes = $_MIDCOM->configuration->normalize_routes($_MIDCOM->configuration->get('routes'));
0
         
0
         if ( !isset($_MIDCOM->context->component_instance)
0
             || !$_MIDCOM->context->component_instance)
0
@@ -174,11 +174,12 @@ class midcom_core_services_dispatcher_midgard implements midcom_core_services_di
0
             return $this->core_routes;
0
         }
0
         
0
- $this->component_routes = $_MIDCOM->context->component_instance->configuration->get('routes');
0
+ $this->component_routes = $_MIDCOM->configuration->normalize_routes($_MIDCOM->context->component_instance->configuration->get('routes'));
0
         
0
         return array_merge($this->core_routes, $this->component_routes);
0
     }
0
 
0
+
0
     /**
0
      * Load a component and dispatch the request to it
0
      */
0
@@ -217,13 +218,35 @@ class midcom_core_services_dispatcher_midgard implements midcom_core_services_di
0
 
0
         $selected_route_configuration = $route_definitions[$this->route_id];
0
 
0
+ // Handle allowed HTTP methods
0
+ header('Allow: ' . implode(', ', $selected_route_configuration['allowed_methods']));
0
+ if (!in_array($_SERVER['REQUEST_METHOD'], $selected_route_configuration['allowed_methods']))
0
+ {
0
+ throw new midcom_exception_httperror("{$_SERVER['REQUEST_METHOD']} not allowed", 405);
0
+ }
0
+
0
         // Initialize controller
0
         $controller_class = $selected_route_configuration['controller'];
0
         $controller = new $controller_class($_MIDCOM->context->component_instance);
0
         $controller->dispatcher = $this;
0
         
0
- // Then call the route_id
0
+ // Define the action method for the route_id
0
         $action_method = "action_{$selected_route_configuration['action']}";
0
+
0
+ // Handle HTTP request
0
+ switch ($_SERVER['REQUEST_METHOD'])
0
+ {
0
+ case 'GET':
0
+ case 'POST':
0
+ // Short-cut these types directly to the controller
0
+ break;
0
+ default:
0
+ // For others, start the full WebDAV server instance
0
+ $webdav_server = new midcom_core_helpers_webdav($controller);
0
+ $webdav_server->serve($this->route_id, $action_method, $this->action_arguments);
0
+ // This will exit
0
+ }
0
+
0
         // TODO: store this array somewhere where it can be accessed via get_context_item
0
         $data = array();
0
         if ($_MIDCOM->timer)
0
@@ -312,44 +335,6 @@ class midcom_core_services_dispatcher_midgard implements midcom_core_services_di
0
         return preg_replace('%/{2,}%', '/', $_MIDCOM->context->prefix . $link);
0
     }
0
 
0
- /**
0
- * Normalizes given route definition ready for parsing
0
- *
0
- * @param string $route route definition
0
- * @return string normalized route
0
- */
0
- public function normalize_route($route)
0
- {
0
- // Normalize route
0
- if ( strpos($route, '?') === false
0
- && substr($route, -1, 1) !== '/')
0
- {
0
- $route .= '/';
0
- }
0
- return preg_replace('%/{2,}%', '/', $route);
0
- }
0
-
0
- /**
0
- * Splits a given route (after normalizing it) to it's path and get parts
0
- *
0
- * @param string $route reference to a route definition
0
- * @return array first item is path part, second is get part, both default to boolean false
0
- */
0
- public function split_route(&$route)
0
- {
0
- $route_path = false;
0
- $route_get = false;
0
- $route = $this->normalize_route($route);
0
- // Get route parts
0
- $route_parts = explode('?', $route, 2);
0
- $route_path = $route_parts[0];
0
- if (isset($route_parts[1]))
0
- {
0
- $route_get = $route_parts[1];
0
- }
0
- unset($route_parts);
0
- return array($route_path, $route_get);
0
- }
0
 
0
     /**
0
      * Tries to match one route from an array of route definitions
0
@@ -377,7 +362,7 @@ class midcom_core_services_dispatcher_midgard implements midcom_core_services_di
0
         {
0
             // Reset variables
0
             $this->action_arguments = array();
0
- list ($route_path, $route_get) = $this->split_route($route);
0
+ list ($route_path, $route_get, $route_args) = $_MIDCOM->configuration->split_route($route);
0
 
0
             //echo "DEBUG: route_id: {$route_id} route:{$route} argv_str:{$argv_str}\n";
0
 
0
@@ -419,8 +404,16 @@ class midcom_core_services_dispatcher_midgard implements midcom_core_services_di
0
             
0
             foreach ($route_path_matches[1] as $index => $varname)
0
             {
0
- preg_match('/{$([a-zA-Z]+):([a-zA-Z]+)}/', $varname, $matches);
0
- $type_hint = $matches[0];
0
+ preg_match('%/{\$([a-zA-Z]+):([a-zA-Z]+)}/%', $varname, $matches);
0
+
0
+ if(count($matches) == 0)
0
+ {
0
+ $type_hint = '';
0
+ }
0
+ else
0
+ {
0
+ $type_hint = $matches[1];
0
+ }
0
                 
0
                 // Strip type hints from variable names
0
                 $varname = preg_replace('/^.+:/', '', $varname);
0
@@ -483,8 +476,16 @@ class midcom_core_services_dispatcher_midgard implements midcom_core_services_di
0
                 return false;
0
             }
0
             
0
- preg_match('/{$([a-zA-Z]+):([a-zA-Z]+)}/', $route_get_matches[2][$index], $matches);
0
- $type_hint = $matches[0];
0
+ preg_match('%/{\$([a-zA-Z]+):([a-zA-Z]+)}/%', $route_get_matches[2][$index], $matches);
0
+
0
+ if(count($matches) == 0)
0
+ {
0
+ $type_hint = '';
0
+ }
0
+ else
0
+ {
0
+ $type_hint = $matches[1];
0
+ }
0
                 
0
             // Strip type hints from variable names
0
             $varname = preg_replace('/^.+:/', '', $route_get_matches[2][$index]);

Comments

    No one has commented yet.