mmghv / lumen-route-binding Goto Github PK
View Code? Open in Web Editor NEWAdds support for route-model-binding in Lumen (Explicit, Implicit, Composite)
License: MIT License
Adds support for route-model-binding in Lumen (Explicit, Implicit, Composite)
License: MIT License
Stack:
laravel/lumen-framework: 5.6.*
, mmghv/lumen-route-binding: ^1.0
I integrated FormRequests into my project. Now I need to access bound model in one of my FormRequests, but don't know how to do it.
I have a route:
$router->put('{user}', 'UserController@update');
And a controller method, where UpdateRequest is a subclass of a FormRequest:
public function update(User $user, UpdateRequest $request): JsonResponse
{
...
}
Also, I have this line in RouteBindingServiceProvider
:
$binder->bind('user', \Core\Users\Entity\User::class);
So, the question is how to access/resolve already bound instance of a User model inside UpdateRequest, which has this contents:
class UpdateRequest extends FormRequest
{
public function rules()
{
// Need to access bound model here
}
}
Hi I am using Lumen
"php": ">=7.1.0",
"laravel/lumen-framework": "7.0.0",
"mmghv/lumen-route-binding": "^1.5"
When I dump data in boot method it works, and shows me the model, but in controller it does not give me model but a new instance.
I have explained my question on StackOverFlow
Undefined variable: binder in web.php ( routes file )
NOTE
This documentation is for dingo/api
version 1.*
, for recent versions of dingo/api
, follow the latest documentations.
Create the following class named DingoAdapter
that will extend the class Dingo\Api\Routing\Adapter\Lumen
and put it somewhere, lets say in app/Custom
:
// app/Custom/DingoAdapter.php
namespace App\Custom;
use Illuminate\Http\Request;
use Dingo\Api\Exception\UnknownVersionException;
use Dingo\Api\Routing\Adapter\Lumen as BaseDingoAdapter;
class DingoAdapter extends BaseDingoAdapter
{
/**
* Dispatch a request.
*
* @param \Illuminate\Http\Request $request
* @param string $version
*
* @return mixed
*/
public function dispatch(Request $request, $version)
{
if (! isset($this->routes[$version])) {
throw new UnknownVersionException;
}
$this->removeMiddlewareFromApp();
$routes = $this->routes[$version];
// This is what we extended the class for, to use the dispatcher created
// by LumenRouteBinding instead of creating a new one.
$this->app['dispatcher']->setRoutesResolver(function() use ($routes) {
return $routes->getData();
});
$this->normalizeRequestUri($request);
return $this->app->dispatch($request);
}
}
Next we need to extend the service provider to use the custom class, Create the following class in app/Providers
:
// app/Providers/DingoServiceProvider.php
namespace App\Providers;
use App\Custom\DingoAdapter;
use FastRoute\RouteParser\Std as StdRouteParser;
use FastRoute\DataGenerator\GroupCountBased as GcbDataGenerator;
use Dingo\Api\Provider\LumenServiceProvider as BaseDingoServiceProvider;
class DingoServiceProvider extends BaseDingoServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
parent::register();
// Replace dingo adapter with an extended one to use the dispatcher from LumenRouteBinding
$this->app->singleton('api.router.adapter', function ($app) {
return new DingoAdapter($app, new StdRouteParser, new GcbDataGenerator, '');
});
}
}
Then in bootstrap/app.php
replace the registeration of dingo
service provider with the custom one:
// remove this line
$app->register(Dingo\Api\Provider\LumenServiceProvider::class);
// and add this line
$app->register(App\Providers\DingoServiceProvider::class);
And don't forget to register the LumenRouteBinding
service provider itself
$app->register(App\Providers\RouteBindingServiceProvider::class);
That's it, Now you shoud be able to use LumenRoutebinding
with DingoAPI
.
Hello there,
Can you please add 7.x to the supported Lumen versions?
Thank you very much!
I recently updated my website to Lumen 5.5 and didn't realize that this did not support it. Luckily, the only change which appears to be necessary is here.
foreach ($this->app->routes->getRoutes() as $route) {
I only just started to test this but that does make my application work again.
Hi, I'm using the lumen-route-binding with Dingo in my project.I do as the doc steps, but it's still not work.Here's my part of my code:
RouteBindingServiceProvider
namespace App\Providers;
use mmghv\LumenRouteBinding\RouteBindingServiceProvider as BaseServiceProvider;
class RouteBindingServiceProvider extends BaseServiceProvider
{
/**
* Boot the service provider
*/
public function boot()
{
// The binder instance
$binder = $this->binder;
// Here we define our bindings
$binder->bind('channel', 'App\Models\Channel');
}
}
app.php
$app->register('App\Providers\RouteBindingServiceProvider');
route.php
//Thread List
$api->get('{channel}/threads', [
'as' => 'threads.index',
'uses' => 'ThreadsController@index',
]);
ThreadsController
public function index(Channel $channel, ThreadFilters $filters)
{
$threads = $this->getThreads($channel, $filters);
return $this->response->paginator($threads, new ThreadTransformer());
}
I can not the get the channel.Can you help me?Many thanks!
First, thanks for your package. I have tried it with complete setup of dusterio/lumen-passport to protect some private endpoints using the auth middleware as you can see in the routes down below.
RouteBindingServiceProvider // Use a custom method on ArticleRepository class
`
... $binder->implicitBind('App\Repositories', '', 'Repository', 'findForRoute'); ...
`
ArticleRepository class
`
... public function findForRoute($val) { return $this->articleModel->where('slug', $val)->firstOrFail(); } ...
`
routes
`
... $router->group(['middleware' => ['auth'], 'prefix' => 'articles'], function () use ($router) { $router->get('/', 'ArticleController@index')->name('api.get.articles'); $router->post('/', 'ArticleController@store')->name('api.post.article); $router->get('/{article}', 'ArticleController@show')->name('api.get.article'); $router->put('/{article}', 'ArticleController@update')->name('api.put.article'); $router->patch('/{article}', 'ArticleController@update')->name('api.patch.article'); $router->delete('/{article}', 'ArticleController@destroy')->name('api.delete.article'); }); ...
`
While testing from Postman to the route 'api.get.article' without a good bearer token on the address http://myapi.com/articles/1 to get an article that does not exist, the reply weirdly throws ModelNotFound exception instead of Authentication exception from the middleware. Weirdly enough, with a good bearer token, I notice proper reply with an Authentication exception as unauthenticated.
I have double checked MySQL log while doing the test, it also shows the query executed related to the get request. It looks all routes binding to {article} affected the same issue.
With the existing issue, I really hate someone may check if a particular article or other important model exists just try the method with any random ID without authenticated. This could be a vulnerability/security, minor or major as it could affect the user of the framework.
I wish you or anyone could fix as soon as possible.
Thank you.
sornss
app/Providers/RouteBindingServiceProviderp.php
class RouteBindingServiceProvider extends BaseServiceProvider
{
public function boot(): void
{
$binder = $this->binder;
$binder->implicitBind('App\Models',);
}
}
bootstrap/app.php
$app->register(App\Providers\AppServiceProvider::class);
$app->register(App\Providers\AuthServiceProvider::class);
$app->register(App\Providers\RouteBindingServiceProvider::class);
routes/web.php
$router->group(['middleware' => ['auth:api']], static function () use ($router) {
$router->group(['prefix' => 'users'], static function () use ($router) {
$router->get('addresses/{address}/edit',['as' => 'user.address.edit', 'action' => 'UserAddressesController@update']);
});
});
request: https://api.test/users/addresses/12345/edit
exception:
{
"status": "fail",
"code": 500,
"message": "Internal Server Error",
"data": {
"message": "Unable to resolve route handler.",
"exception": "RuntimeException",
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php",
"line": 295,
"trace": [
{
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php",
"line": 259,
"function": "callActionOnArrayBasedRoute",
"class": "Laravel\\Lumen\\Application",
"type": "->"
},
{
"function": "Laravel\\Lumen\\Concerns\\{closure}",
"class": "Laravel\\Lumen\\Application",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Routing/Pipeline.php",
"line": 48,
"function": "call_user_func"
},
{
"file": "/Users/wilbur/api/app/Http/Middleware/AuthenticateMiddleware.php",
"line": 23,
"function": "Laravel\\Lumen\\Routing\\{closure}",
"class": "Laravel\\Lumen\\Routing\\Pipeline",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/illuminate/pipeline/Pipeline.php",
"line": 167,
"function": "handle",
"class": "App\\Http\\Middleware\\AuthenticateMiddleware",
"type": "->"
},
{
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Routing/Pipeline.php",
"line": 30,
"function": "call_user_func"
},
{
"file": "/Users/wilbur/api/vendor/illuminate/pipeline/Pipeline.php",
"line": 103,
"function": "Laravel\\Lumen\\Routing\\{closure}",
"class": "Laravel\\Lumen\\Routing\\Pipeline",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php",
"line": 423,
"function": "then",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php",
"line": 260,
"function": "sendThroughPipeline",
"class": "Laravel\\Lumen\\Application",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php",
"line": 234,
"function": "handleFoundRoute",
"class": "Laravel\\Lumen\\Application",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php",
"line": 170,
"function": "handleDispatcherResponse",
"class": "Laravel\\Lumen\\Application",
"type": "->"
},
{
"function": "Laravel\\Lumen\\Concerns\\{closure}",
"class": "Laravel\\Lumen\\Application",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Routing/Pipeline.php",
"line": 48,
"function": "call_user_func"
},
{
"file": "/Users/wilbur/api/app/Http/Middleware/AcceptHeaderMiddleware.php",
"line": 27,
"function": "Laravel\\Lumen\\Routing\\{closure}",
"class": "Laravel\\Lumen\\Routing\\Pipeline",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/illuminate/pipeline/Pipeline.php",
"line": 167,
"function": "handle",
"class": "App\\Http\\Middleware\\AcceptHeaderMiddleware",
"type": "->"
},
{
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Routing/Pipeline.php",
"line": 30,
"function": "call_user_func"
},
{
"file": "/Users/wilbur/api/vendor/fideloper/proxy/src/TrustProxies.php",
"line": 57,
"function": "Laravel\\Lumen\\Routing\\{closure}",
"class": "Laravel\\Lumen\\Routing\\Pipeline",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/illuminate/pipeline/Pipeline.php",
"line": 167,
"function": "handle",
"class": "Fideloper\\Proxy\\TrustProxies",
"type": "->"
},
{
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Routing/Pipeline.php",
"line": 30,
"function": "call_user_func"
},
{
"file": "/Users/wilbur/api/vendor/illuminate/pipeline/Pipeline.php",
"line": 103,
"function": "Laravel\\Lumen\\Routing\\{closure}",
"class": "Laravel\\Lumen\\Routing\\Pipeline",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php",
"line": 423,
"function": "then",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php",
"line": 172,
"function": "sendThroughPipeline",
"class": "Laravel\\Lumen\\Application",
"type": "->"
},
{
"file": "/Users/wilbur/api/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php",
"line": 109,
"function": "dispatch",
"class": "Laravel\\Lumen\\Application",
"type": "->"
},
{
"file": "/Users/wilbur/api/public/index.php",
"line": 28,
"function": "run",
"class": "Laravel\\Lumen\\Application",
"type": "->"
}
]
}
}
Hello ,
I create RouteBindingServiceProvider.php in app/Providers and then I register the provider in the app.php
but still gives me this error
Class 'app/Providers/RouteBindingServiceProvider' not found
Any chance we can add support for Laravel/Lumen 8.x?
I can't see any breaking changes in Lumen 8 so assume it should be as simple as just updating the package dependencies...
Stack: laravel/lumen-framework: 5.8.12, mmghv/lumen-route-binding: 1.4.2
I enabled the auth middleware in my project using the TokenGuard
. In bootstrap/app.php:
$app->routeMiddleware([
'auth' => App\Http\Middleware\Authenticate::class
]);
In routes/web.php:
$router->group(['middleware' => 'auth'], function ($route) {
$route->get('/posts/{post}', 'PostController@show');
...
});
The problem is, the code looks for the post object before checking if there is an authenticated user.
Is there a way for the auth middleware to execute first instead of the route binding so it would throw an AuthenticationException without querying for the model?
This has been solved in Laravel using SubstituteBinding middleware: #6118
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.