I have a route defined as:
Route::resource('item', 'ItemController');
What I want to do is put some of these routes, particularly edit and delete inside a group.
Route::group(['middleware' => ['role']], function() {
Route::resource('item', 'ItemController', ['only' => ['edit', 'delete']]);
}
This doesn't work, though. Do I have to define each route one by one then? Or is there a better solution to this?
EDIT:
I'm sorry, but it seems I did not ask the question properly. So let me make some clarifications here.
I have a basic auth user which can create and view items. What I don't want it to do is edit and delete.
I then also have a role user which do everything auth can do AND edit and delete items.
So basically, regular authorized users can have SOME access to items while role users have COMPLETE access.
The current code seems to give role users ONLY edit and delete functionalities and no view or create.
To make it even more clearer, here's what my actual route looks like:
Route::group(['middleware' => ['auth']], function()
{
Route::resource('items', 'SitesController');
Route::group(['middleware' => ['role']], function() {
Route::resource('item', 'ItemController', ['only' => ['edit', 'delete']]);
});
});
Maybe I'm going about this the wrong way?
The code above will work, you just named the action incorrectly. You should have used destroy instead of delete. Try the following code:
Route::resource('item', 'ItemController');
Route::group(['middleware' => ['role']], function() {
Route::resource('item', 'ItemController', ['only' => ['edit', 'destroy']]);
});
You can run php artisan route:list to verify. You should see role middleware enabled in 2 of your routes.
Related
I am just getting started with Laravel and find the route setup a little confusing. I am trying to create a few pages, that ultimately should have the struture:
domain.com/onboarding
domain.com/onboarding/skip
domain.com/onboarding/skip/anothersubview
etc.
Right now I have:
// Registered and Activated User Routes
Route::group(['middleware' => ['auth', 'activated', 'activity']], function () {
Route::get('/onboarding', 'UserController#Onboarding')->name('onboarding');
});
Would the solution here (and best practice) be to just add another route inside my Route::group, like:
Route::view('/onboarding/skip', 'onboarding.skip');
Is this the correct way of doing things?
use prefix :
Route::group(['prefix' => 'onboarding','middleware' => ['auth', 'activated', 'activity']], function () {
Route::get('/', 'UserController#Onboarding')->name('onboarding');
Route::get('/skip', 'UserController#OnboardingSkip')->name('onboarding_skip');
Route::get('/skip/anothersubview', 'UserController#OnboardingSkipSubview')->name('onboarding_skipsubview');
});
read more here : https://laravel.com/docs/5.6/routing
The structure I used in a few projects in the past looks like this:
Route::group(['prefix' => 'onboarding'], function(){
Route::group(['prefix' => 'something'], function(){
Route::get('/', function(){}); //onboarding/something
Route::group(['prefix' => 'somethingelse'], function(){
Route::get('/', function(){}); //onboarding/something/somethingelse
Route::get('/{id}', function(){}); //onboarding/something/somethingelse/15
});
});
});
nesting groups can help you make the easier extendable router because when you realize you need to add some URL in the middle of long structure it would be easier to do it with this concept
You have a web.php file in your routes folder, there you need to add:
Route::get('/subpage', 'controllername#function-name-you-want-to-call');
Hope this helps, if it doesn't let me know
/e: to clarify:
the first part
Route::group(['middleware' => ['auth', 'activated', 'activity']], function () {
is the authentication. Depending on who you want to access this page, you might not need it
At first I decided to organize my routes like I have in the code given below. However, I quickly realized that I couldn't access the routes in the group that uses middleware guest as soon as I log in. Does that mean that routes which I want to be accessible by anyone no matter whether they're logged in or not should not be in any middleware group?
<?php
Route::group(['middleware' => ['web']], function(){
Route::group(['middleware' => ['guest']], function(){
Route::get('/', 'PagesController#index')->name('home');
Route::get('/image/{id}', 'PagesController#specificImage')->name('specificImage');
Route::get('/contact', 'PagesController#contact')->name('contact');
Route::get('/tags', 'PagesController#tags')->name('tags');
Route::get('/tags/{tagName}', 'PagesController#specificTag')->name('specificTag');
Route::get('/albums', 'PagesController#albums')->name('albums');
Route::get('/albums/{albumId}/{albumName}', 'PagesController#specificAlbum')->name('specificAlbum');
Route::post('/signup', 'UsersController#signUp')->name('signup');
Route::post('/signin', 'UsersController#signIn')->name('signin');
Route::post('/sendmail', 'UsersController#sendMail')->name('sendmail');
});
Route::group(['middleware' => ['auth']], function(){
Route::get('/upload', 'PagesController#upload')->name('upload');
Route::get('/logout', 'UsersController#logOut')->name('logout');
Route::get('/imageDelete/{imageId}', 'ImagesController#deleteImage')->name('deleteImage');
Route::get('/deleteTag/{tagId}', 'TagsController#deleteTag')->name('deleteTag');
Route::post('/imageUpload', 'ImagesController#uploadImage')->name('imageUpload');
Route::post('/albumUpload', 'AlbumsController#uploadAlbum')->name('albumUpload');
Route::post('/createTag', 'TagsController#createTag')->name('createTag');
});
});
Remove auth middleware from the route group
Correct! Get rid of the guest middleware, you don't need it.
Just Do not use any middleware.
I have a web app with 2 users types: admins and customers. In my users table I have a boolean column named "is_admin". When admins login, they should have access to one set of resources; when users login, they should have access to another set of resources.
I have a feeling I need to use either middleware or policies, but cannot find any good examples online.
Any help would be much appreciated.
This is the code from my web.php routes file
Auth::routes();
Route::group(['middleware' => ['auth']], function () {
Route::get('/', 'DashboardController#index')->name('dashboard');
Route::resource('stock-types', 'StockTypeController');
Route::resource('stock-items', 'StockItemController');
Route::resource('companies', 'CompanyController');
Route::resource('addresses', 'AddressController');
Route::resource('contacts', 'ContactController');
Route::resource('deliveries', 'DeliveryController');
Route::resource('settings', 'SettingController', ['only' => [
'index', 'update',
]]);
Route::resource('users', 'UserController');
});
This in an example for admin check
https://laracasts.com/discuss/channels/general-discussion/create-middleware-to-auth-admin-users?page=1
In my Laravel app I have a resource route where I want to control access to individual routes based on a filter. I do this by declaring the resource with only the "view" routes and then declaring it again with only the "edit/create" routes in a nested filtered group. The filter is a custom one that check the logged-in user's capabilities.
My routes looks like this:
Route::group(['before' => 'auth'], function()
{
$edit_routes = ['create', 'store', 'destroy', 'edit', 'update'];
Route::resource('things', 'ThingsController', ['except' => $edit_routes]);
// We'll filter the routes that involve editing resources
Route::group(['before' => 'edit_resource'], function() use ($edit_routes)
{
Route::resource('things', 'ThingsController', ['only' => $edit_routes]);
});
}
Is this correct? It seems not to work, although no errors are thrown. When I visit a route in the nested filter (e.g. things/create) I just get a blank page.
Is there a better way of achieving this?
Is this correct?
No
Is there a better way of achieving this?
Yes. Here is a great blog post by Phil Sturgeon that explains why you should just define each route manually.
If you really want to continue using the Resource Controller, you can apply the edit_resource inside the controller constructor like this:
Route::resource('things', 'ThingsController', ['before' => 'auth']);
Then in your resource controller
public function __construct()
{
$this->beforeFilter('edit_resource', array('only' => ['create', 'store', 'destroy', 'edit', 'update']);
}
Is there a way to cleanly group all routes starting with admin/?
I tried something like this, but it didn't work ofcourse:
Route::group('admin', function()
{
Route::get('something', array('uses' => 'mycontroller#index'));
Route::get('another', array('uses' => 'mycontroller#second'));
Route::get('foo', array('uses' => 'mycontroller#bar'));
});
Corresponding to these routes:
admin/something
admin/another
admin/foo
I can ofcourse just prefix all those routes directly with admin/, but I'd like to know if it's possible to do it my way.
Thanks!
Unfortunately no. Route groups were not designed to work like that. This is taken from the Laravel docs.
Route groups allow you to attach a set of attributes to a group of routes, allowing you to keep your code neat and tidy.
A route group is used for applying one or more filters to a group of routes. What you're looking for is bundles!
Introducing Bundles!
Bundles are what you're after, by the looks of things. Create a new bundle called 'admin' in your bundles directory and register it in your application/bundles.php file as something like this:
'admin' => array(
'handles' => 'admin'
)
The handles key allows you to change what URI the bundle will respond to. So in this case any calls to admin will be run through that bundle. Then in your new bundle create a routes.php file and you can register the handler using the (:bundle) placeholder.
// Inside your bundles routes.php file.
Route::get('(:bundle)', function()
{
return 'This is the admin home page.';
});
Route::get('(:bundle)/users', function()
{
return 'This responds to yoursite.com/admin/users';
});
Hope that gives you some ideas.
In Laravel 4 you can now use prefix:
Route::group(['prefix' => 'admin'], function() {
Route::get('something', 'mycontroller#index');
Route::get('another', function() {
return 'Another routing';
});
Route::get('foo', function() {
return Response::make('BARRRRR', 200);
});
Route::get('bazz', function() {
return View::make('bazztemplate');
});
});