How to check value of parameters of RESTful controller's action - laravel

I use the Larvel 4.1
If I use routes for every action I can check parameters value into route like here
Route::get('user/{id}', 'UserController#showProfile')->where('id', '[0-9]+');
But I don't understand how to check this value when I define a route for a RESTful controller
Route::controller('users', 'UserController');
Do I check parameters directly into controller's action or there is another way?

Yeah, looks like this is not the way Route::controller() works, but if you do
Route::pattern('one', '[0-9]+');
It will work. Because this is how Laravel create controller routes parameters:
GET|HEAD myactions/id/{one?}/{two?}/{three?}/{four?}/{five?}
The problem is that you cannot filter those parameters this way because they may appear in actions of different controllers. So you probably will have to create some of those routes manually:
Route::get('user/{id}', 'UserController#showProfile')->where('id', '[0-9]+');
Which, in my opinion is better than use a generic Route::controller() or Route::resource(). And in Phil Sturgeon's opinion too, as you can see in his article: http://philsturgeon.uk/blog/2013/07/beware-the-route-to-evil

So, I actually use separated routes for each action this manner
Route::pattern('one', '[0-9]+');
Route::get('user/{id}', 'UserController#showProfile');
I simple was hoped do it in more short way.

Related

Product And Category Separation In Route (Laravel)

I'm setting up a new route system.
Route::get('/{cat1Url}', 'CategoryController#showCat1')->name('showCat1');
Route::get('/{productUrl}', 'ProductController#showProduct')->name('showProduct');
My sef link is after "/"
But,
{{ route('showProduct',[$p->pr_url]) }}
This method not working with route name. Working only upside route.
I don't want use
"/cat/myVariable"
or
"/product/myVariable"
Can't I use route name to work this way?
What is the solution to this?
In this way, if you make a get request to /something the laravel you start from top of web.php file looking to a route that follows the pattern. Your both routes will follow that pattern, but the laravel will always, pass the first one to controller.
You have two options:
Put only one route, and inside the controller you switch to the appropriate function. But this isn't a great ideia, because this is the function of the Web.php.
Use the routes like the documentation recommend:
Route::get('/cat/{catId}', 'CategoryController#showCat')->name('showCat');
Route::get('/prod/{productId}', 'ProductController#showProduct')->name('showProduct');
and in Controller you make the appropriate handler of your Category or Product.
You will have to have a way to tell Laravel which url to be mapped to what otherwise it will always use the last defined route. So in your case calling /myVariable and /myVariable it will use the latest definition which is showProduct. The only other way is if you use regular expression to differentiate the variables. For example:
Route::get('/{cat1Url}', 'CategoryController#showCat1')
->name('showCat1')->where('cat1Url', 'cat-*');
Route::get('/{productUrl}', 'ProductController#showProduct')
->name('showProduct')->where('productUrl', 'prod-*');
This way your slugs need to start with what you define, but you cannot use just id as a numeric value for both.

How to declare routes with resources in Laravel 5.2

I have some routes in routes.php in laravel
// Code for rounting admin panel
Route::resource('/admin','Admin\LoginController#index');
Route::resource('/admin/dashboard','Admin\AdminController#index');
Route::resource('/admin/movies','Admin\MovieController#index');
Now when I access url http://localhost/askspidy/admin I want to show login page and it works, but when i access url http://localhost/askspidy/admin/dashboard it should go to dashboard but it's showing me login page only.
I know this is because when it found /admin in any url it's bydefault goes to the route
Route::resource('/admin','Admin\LoginController#index');
I know it's assuming that (/admin) is route to controller and (/dashboard) is the function declared in the controller but I want routing like this only so is there any other solution for this problem.
A RESTful Resource Controller takes over the responsibility of each action. You only need to list the name and the controller:
Route::resource('photo', 'PhotoController');
If you wanted to only use the index method, you’d list it like this:
Route::resource('photo', 'PhotoController', ['only' => [
'index'
]]);
However, it looks like two of your routes are not suitable for resources (login and dashboard), as they should relate to editing a model.
You should instead just use a get() resource instead.
From the docs:
Route::get('user/{id}', 'UserController#showProfile');
So in your case, it would be:
Route::get('/admin','Admin\LoginController#index');
Route::get('/admin/dashboard','Admin\AdminController#index');
Route::resource('/admin/movie','Admin\MovieController');

Laravel 5 - Assign Middleware to Controller Namespace

I need to do an ACL check for the user before allowing access to the admin panel of a Laravel 5 website. What is the best way to do this for an entire controller group in the namespace App\Http\Controllers\Admin\*? Ultimately, I'm looking for a "set and forget" method to do this, and middleware looks like the best option so far.
The initial idea was to assign a middleware to the admin route, but this does not prevent any other non-admin route from accessing the controllers. This means a route can still target the admin controllers and bypass the ACL check.
The next idea was to insert the assignment in the constructor on the controllers, but this would require each additional controller to explicitly include the middleware. This would require a developer to know that the middleware should be included, which allows them to miss it entirely. This also applies to using one base controller as the parent for all admin controllers, since the developer would need to know that the base controller should be extended. Right now, this looks like the best solution.
This leads us back to the question: can middleware be assigned to a controller wildcard namespace like App\Http\Controllers\Admin\*? Or, is there a better way for the ACL check to never need to be explicitly assigned to every admin controller?
This leads us back to the question: can middleware be assigned to a controller wildcard namespace like App\Http\Controllers\Admin*?
No
The most simplest approach you can do is create a base controller such as App\Http\Controllers\Admin\Controller and include the middleware
while all other App\Http\Controllers\Admin\* extends it.
Alternatively, while still adding App\Http\Controllers\Admin\Controller, you could instead inject the middleware through IoC Container.
App::afterResolving('App\Http\Controllers\Admin\Controller', function ($controller) {
$controller->middleware('acl');
});
EDIT
My previous answer didn't quite work for all situations; it broke a lot of other routes. Here's what I ended up doing instead (in app/Http/routes.php):
Route::group(['namespace' => 'Admin', 'prefix' => 'admin', 'middleware' => 'App\Http\Middleware\Acl'], function()
{
Route::get('/', 'AdminController#index');
Route::get('/user', 'User\UserController#index');
...
});
This at least targets all admin controllers when I define a route. It's not exactly everything I had hope for, but it will do.

Laravel Controller Delegation

Trying to keep my Laravel project organized here, while letting it grow.
Currently I use:
Route::controller('/admin', 'AdminController');
...in order to allow the controller to service general admin pages. This is working fine, however I'd like to delegate specific subqueries to other controllers for cleanliness reasons.
For example, I'd like /admin/dashboard to resolve to AdminController#getDashboard. I'd also like /admin/gallery/ to resolve to AdminGalleryController#getIndex, and /admin/foo/bar to resolve to AdminFooController#getBar.
Is there a simple way to slowly expand functionality like this?
We've migrated to Laravel 5 and 5.1, and this still remains a good way to do things. If you aren't using route groups in Laravel, then you aren't doing Laravel right.
You can define those others as controller routes as well. Just do it before Route::controller('admin') because Laravel searches the registered routes in the other you define them. Since /admin/gallery would match Route::controller('admin') as well as Route::controller('admin/gallery') latter has to be defined first:
Route::controller('admin/gallery', 'AdminGalleryController');
Route::controller('admin/foo', 'AdminFooController');
Route::controller('admin', 'AdminController');
Instead of writing admin every time a route group might be a nice improvement as well:
Route::group(['prefix' => 'admin'], function(){
Route::controller('gallery', 'AdminGalleryController');
Route::controller('foo', 'AdminFooController');
Route::controller('/', 'AdminController');
});
Yes. Simply declare your "exception" routes before your main controller route.
Route::get('/admin/gallery','AdminGalleryContoller#getIndex');
Route::get('/admin/dashboard','AdminController#getDasboard');
Route::controller('/admin','AdminController');

Laravel 4.x, using both controller & resource routing

I'm trying using this:
Route::resource('users', 'UserController');
Route::controller('users', 'UserController');
When I'm using one of them - WORK,
otherwise - only resource work.
There is an option to using them both?
Which ever is on-top will take priority so if you put Route::controller on-top then that's the one that would work. I would post this as a comment but I don't have the rep to do it. Also why would you wanna use both of them at the same time?
Try moving Route::controller declaration above Route::resource:
Route::controller('users', 'UserController');
Route::resource('users', 'UserController');
The thing is that Laravel tries to match request with your defined routes by going from top to bottom and stops when it finds one.
localhost/users/example in your example actually hits show method in your UserController class as explained in documentation (see Actions Handled By Resource Controller).
Therefore Route::controller('users', 'UserController'); is ignored in this case.
I believe it's only working with one because once you use Route::resource(), all routes starting with users is going to be grabbed, and since Route::resource() does not work by prepending the action with the last segement in the uri (public function getUsers()), it's failing.
With your example provided, all you should need to use is Route::controller(). If there are some cases where that won't do, before it, add whatever routes you need using Route::get(), Route::post() or Route::any()
Route::resource() and Route::controller() were I believe not designed to work together and there shouldn't be much need to actually use them together.

Resources