Skip to content

Commit

Permalink
Allow dynamically adding of routes during caching
Browse files Browse the repository at this point in the history
  • Loading branch information
driesvints committed Mar 7, 2020
1 parent eca3517 commit 5743fdf
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 87 deletions.
95 changes: 43 additions & 52 deletions src/Illuminate/Routing/CompiledRouteCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
use Illuminate\Container\Container;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
Expand All @@ -26,6 +28,13 @@ class CompiledRouteCollection extends AbstractRouteCollection
*/
protected $attributes = [];

/**
* An array of the routes that were added after loading the compiled routes.
*
* @var \Illuminate\Routing\RouteCollection|null
*/
protected $routes;

/**
* The router instance used by the route.
*
Expand All @@ -51,6 +60,7 @@ public function __construct(array $compiled, array $attributes)
{
$this->compiled = $compiled;
$this->attributes = $attributes;
$this->routes = new RouteCollection;
}

/**
Expand All @@ -61,21 +71,7 @@ public function __construct(array $compiled, array $attributes)
*/
public function add(Route $route)
{
$name = $route->getName() ?: $this->generateRouteName();

$this->attributes[$name] = [
'methods' => $route->methods(),
'uri' => $route->uri(),
'action' => $route->getAction() + ['as' => $name],
'fallback' => $route->isFallback,
'defaults' => $route->defaults,
'wheres' => $route->wheres,
'bindingFields' => $route->bindingFields(),
];

$this->compiled = [];

return $route;
return $this->routes->add($route);
}

/**
Expand Down Expand Up @@ -108,41 +104,32 @@ public function refreshActionLookups()
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Routing\Route
*
* @throws \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function match(Request $request)
{
if (empty($this->compiled) && $this->attributes) {
$this->recompileRoutes();
}

$route = null;

$matcher = new CompiledUrlMatcher(
$this->compiled, (new RequestContext)->fromRequest($request)
);

$route = null;

try {
if ($result = $matcher->matchRequest($request)) {
$route = $this->getByName($result['_route']);
}
} catch (ResourceNotFoundException | MethodNotAllowedException $e) {
//
try {
return $this->routes->match($request);
} catch (NotFoundHttpException | MethodNotAllowedHttpException $e) {
//
}
}

return $this->handleMatchedRoute($request, $route);
}

/**
* Recompile the routes from the attributes array.
*
* @return void
*/
protected function recompileRoutes()
{
$this->compiled = $this->dumper()->getCompiledRoutes();
}

/**
* Get routes from the collection by method.
*
Expand All @@ -162,7 +149,7 @@ public function get($method = null)
*/
public function hasNamedRoute($name)
{
return isset($this->attributes[$name]);
return isset($this->attributes[$name]) || $this->routes->hasNamedRoute($name);
}

/**
Expand All @@ -173,7 +160,11 @@ public function hasNamedRoute($name)
*/
public function getByName($name)
{
return isset($this->attributes[$name]) ? $this->newRoute($this->attributes[$name]) : null;
if (isset($this->attributes[$name])) {
return $this->newRoute($this->attributes[$name]);
}

return $this->routes->getByName($name);
}

/**
Expand All @@ -192,7 +183,11 @@ public function getByAction($action)
return $attributes['action']['uses'] === $action;
});

return $attributes ? $this->newRoute($attributes) : null;
if ($attributes) {
return $this->newRoute($attributes);
}

return $this->routes->getByAction($action);
}

/**
Expand All @@ -202,7 +197,13 @@ public function getByAction($action)
*/
public function getRoutes()
{
return $this->mapAttributesToRoutes()->values()->all();
return collect($this->attributes)
->map(function (array $attributes) {
return $this->newRoute($attributes);
})
->merge($this->routes->getRoutes())
->values()
->all();
}

/**
Expand All @@ -212,7 +213,7 @@ public function getRoutes()
*/
public function getRoutesByMethod()
{
return $this->mapAttributesToRoutes()
return collect($this->getRoutes())
->groupBy(function (Route $route) {
return $route->methods();
})
Expand All @@ -231,21 +232,11 @@ public function getRoutesByMethod()
*/
public function getRoutesByName()
{
return $this->mapAttributesToRoutes()->keyBy(function (Route $route) {
return $route->getName();
})->all();
}

/**
* Get all of the routes in the collection.
*
* @return \Illuminate\Support\Collection
*/
public function mapAttributesToRoutes()
{
return collect($this->attributes)->map(function (array $attributes) {
return $this->newRoute($attributes);
});
return collect($this->getRoutes())
->keyBy(function (Route $route) {
return $route->getName();
})
->all();
}

/**
Expand Down
18 changes: 18 additions & 0 deletions src/Illuminate/Routing/RouteCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Illuminate\Routing;

use Illuminate\Container\Container;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;

Expand Down Expand Up @@ -146,6 +147,7 @@ public function refreshActionLookups()
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Routing\Route
*
* @throws \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function match(Request $request)
Expand Down Expand Up @@ -247,4 +249,20 @@ public function toSymfonyRouteCollection()

return $symfonyRoutes;
}

/**
* Convert the collection to a CompiledRouteCollection instance.
*
* @param \Illuminate\Routing\Router $router
* @param \Illuminate\Container\Container $container
* @return \Illuminate\Routing\CompiledRouteCollection
*/
public function toCompiledRouteCollection(Router $router, Container $container)
{
['compiled' => $compiled, 'attributes' => $attributes] = $this->compile();

return (new CompiledRouteCollection($compiled, $attributes))
->setRouter($router)
->setContainer($container);
}
}
1 change: 1 addition & 0 deletions src/Illuminate/Routing/RouteCollectionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public function refreshActionLookups();
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Routing\Route
*
* @throws \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function match(Request $request);
Expand Down
Loading

0 comments on commit 5743fdf

Please sign in to comment.