diff --git a/core/includes/common.inc b/core/includes/common.inc index a4fcf511ce198c0e056813364ccaddc85f547d82..eeb3fa85d555cb1a775e46778d4b5c69c3f8da39 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -5091,6 +5091,7 @@ function _drupal_bootstrap_full() { require_once DRUPAL_ROOT . '/core/includes/theme.inc'; require_once DRUPAL_ROOT . '/core/includes/pager.inc'; require_once DRUPAL_ROOT . '/' . variable_get('menu_inc', 'core/includes/menu.inc'); + require_once DRUPAL_ROOT . '/core/includes/router.inc'; require_once DRUPAL_ROOT . '/core/includes/tablesort.inc'; require_once DRUPAL_ROOT . '/core/includes/file.inc'; require_once DRUPAL_ROOT . '/core/includes/unicode.inc'; diff --git a/core/includes/router.inc b/core/includes/router.inc new file mode 100644 index 0000000000000000000000000000000000000000..6f979bdfde38b4a0f4227b4cfcef86c6c95d6359 --- /dev/null +++ b/core/includes/router.inc @@ -0,0 +1,75 @@ +<?php + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing; +use Symfony\Component\HttpKernel; + +function router_execute_active_handler($request) { + // Do some hand waving to setup the routing. + $routes = router_get_routes($request); + + try { + // Resolve a routing context(path, etc) using the routes object to a + // Set a /routing/ context to translate + $context = new Routing\RequestContext(); + $context->fromRequest($request); + $matcher = new Routing\Matcher\UrlMatcher($routes, $context); + $request->attributes->add($matcher->match($request->getPathInfo())); + + // Get the controller(page callback) from the resolver. + $resolver = new HttpKernel\Controller\ControllerResolver(); + $controller = $resolver->getController($request); + $arguments = $resolver->getArguments($request, $controller); + + $response = call_user_func_array($controller, $arguments); + } + catch (Routing\Exception\ResourceNotFoundException $e) { + $response = new Response('Not Found', 404); + } + //catch (Exception $e) { + // $response = new Response('An error occurred', 500); + //} + + return $response; +} + +/** + * Get a RouteCollection for resolving a request. + * + * Ok, so... we need a routing collection that's not this "dumb". Symfony's just + * is just a trivial implementation. It probably means we need our own + * DrupalRouteCollection which would actually wrap this logic, our menu router + * table, translating between it, and caching. + */ +function router_get_routes($request) { + $routes = new Routing\RouteCollection(); + foreach (module_list() as $module) { + $func = $module . '_menu'; + $items = $func(); + + foreach ($items as $path => $item) { + // Drupal doesn't prefix but if someone did we wouldn't want to double up. + if (0 !== strpos($path, '/')) { + $path = '/' . $path; + } + + // Set base route array. + $route = array( + // A page callback could be a router. I'm not sure if the controller + // should actually be a thin layer on top or work like this yet. + '_controller' => $item['page callback'], + ); + + // Place argument defaults on the route. + foreach ($item['page arguments'] as $k => $v) { + $route[$k] = $v; + } + // @todo put other "menu" information somewhere. + + $routes->add(hash('sha256', $path), new Routing\Route($path, $route)); + } + } + + return $routes; +} diff --git a/index.php b/index.php index b91fb1ecf1e67d9af3fe92562a4a0fd8495c2ef3..8e6146ee6b95941d1ee8491b07ba2303a3404b80 100644 --- a/index.php +++ b/index.php @@ -16,6 +16,15 @@ */ define('DRUPAL_ROOT', getcwd()); +use Symfony\Component\HttpFoundation\Request; + +// Bootstrap the lowest level of what we need. require_once DRUPAL_ROOT . '/core/includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); -menu_execute_active_handler(); + +// A request object from the HTTPFoundation to tell us about the request. +$request = Request::createFromGlobals(); +// Run our router, get a response. +$response = router_execute_active_handler($request); +// Output response. +$response->send();