Skip to content

Commit

Permalink
Set the bindings from the Laravel router when request is matched.
Browse files Browse the repository at this point in the history
When a request is matched we will also need to grab the route bindings which
include model bindings and set them on the adapters router instance.

We will also simply clone the Laravel router instead of instantiating a
new instance.
  • Loading branch information
jasonlewis committed Mar 21, 2016
1 parent b2eabe1 commit 6193841
Showing 1 changed file with 52 additions and 19 deletions.
71 changes: 52 additions & 19 deletions src/Provider/LaravelServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public function boot()

$this->publishes([realpath(__DIR__.'/../../config/api.php') => config_path('api.php')]);



$kernel = $this->app->make('Illuminate\Contracts\Http\Kernel');

$this->app['Dingo\Api\Http\Middleware\Request']->mergeMiddlewares(
Expand All @@ -30,7 +32,12 @@ public function boot()

$this->addRequestMiddlewareToBeginning($kernel);

$this->replaceRouteDispatcher();

$this->app['events']->listen(RequestWasMatched::class, function (RequestWasMatched $event) {
$this->replaceRouteDispatcher();

$this->updateRouterBindings();
});
}

/**
Expand All @@ -40,13 +47,37 @@ public function boot()
*/
protected function replaceRouteDispatcher()
{
$this->app['events']->listen(RequestWasMatched::class, function (RequestWasMatched $event) {
$this->app->singleton('illuminate.route.dispatcher', function ($app) {
return new ControllerDispatcher($app['api.router.adapter']->getRouter(), $app);
});
$this->app->singleton('illuminate.route.dispatcher', function ($app) {
return new ControllerDispatcher($app['api.router.adapter']->getRouter(), $app);
});
}

/**
* Grab the bindings from the Laravel router and set them on the adapters
* router.
*
* @return void
*/
protected function updateRouterBindings()
{
foreach ($this->getRouterBindings() as $key => $binding) {
$this->app['api.router.adapter']->getRouter()->bind($key, $binding);
}
}

/**
* Get the Laravel routers bindings.
*
* @return array
*/
protected function getRouterBindings()
{
$property = (new ReflectionClass($this->app['router']))->getProperty('binders');
$property->setAccessible(true);

return $property->getValue($this->app['router']);
}

/**
* Register the service provider.
*
Expand All @@ -67,17 +98,23 @@ public function register()
protected function registerRouterAdapter()
{
$this->app->singleton('api.router.adapter', function ($app) {
$router = new Router($app['events'], $app);
return new LaravelAdapter($app, $this->cloneLaravelRouter(), $app['router']->getRoutes());
});
}

$router->middleware('api.auth', 'Dingo\Api\Http\Middleware\Auth');
$router->middleware('api.throttle', 'Dingo\Api\Http\Middleware\RateLimit');
/**
* Clone the Laravel router and set the middleware on the cloned router.
*
* @return \Illuminate\Routing\Router
*/
protected function cloneLaravelRouter()
{
$router = clone $this->app['router'];

foreach ($app['router']->getMiddleware() as $name => $class) {
$router->middleware($name, $class);
}
$router->middleware('api.auth', 'Dingo\Api\Http\Middleware\Auth');
$router->middleware('api.throttle', 'Dingo\Api\Http\Middleware\RateLimit');

return new LaravelAdapter($app, $router, $app['router']->getRoutes());
});
return $router;
}

/**
Expand All @@ -102,13 +139,9 @@ protected function addRequestMiddlewareToBeginning(Kernel $kernel)
*/
protected function gatherAppMiddleware(Kernel $kernel)
{
$reflection = new ReflectionClass($kernel);

$property = $reflection->getProperty('middleware');
$property = (new ReflectionClass($kernel))->getProperty('middleware');
$property->setAccessible(true);

$middleware = $property->getValue($kernel);

return $middleware;
return $property->getValue($kernel);
}
}

0 comments on commit 6193841

Please sign in to comment.