0
votes

I am building an app using Laravel 4.1. My app needs to have two types of different users, admin and clients. To achieve this I have added a type column to the user table and created customs filters in /app/filters.php.

Route::filter('admin', function()
{
    if (Auth::guest() || Auth::user()->type !== 1) return Redirect::to('/');
});

Route::filter('client', function()
{
    if (Auth::guest() || Auth::user()->type != 2) return Redirect::to('/');
});

Then I have created Route::group in /app/routes.php

/* Admin */
Route::group(array('before' => 'admin'), function()
{
    Route::get('admin', function(){ return "admin index"; });
    Route::get('ejemplo', function(){ return "admin ejmplo"; });
});

/* Client */
Route::group(array('before' => 'client'), function()
{
    Route::get('client', function(){ return "client index"; });
    Route::get('ejemplo', function(){ return "client ejmplo"; });
});

The problem that I am facing is that I cant access Route::get('ejemplo'), I thought about a solution for this:

  • Adding if statements within the Route Group, so only Auth::user()->type( [x] ) could access certain routes.

But since I am quite new to laravel I wouldnt like to mess up my code making it unscalable or unmaintainable.

I am open to any other solution or structure design,

Thank you very much in advance. Cheers

2
That's what filters are for...Check if they're working correctly (is type really an int 1, for example?)Damien Pirsy
Yes it is an int, filters work great execpt when the Route::get('url') is repeated,I am experiment naming the routes to see if i can get it workingIban Dominguez Noda
Is the problem that you can't access ejemplo as a client?Marwelln
I cant access ejemplo as a admin but I can access ejemplo as a clientIban Dominguez Noda

2 Answers

0
votes

Don't redefine routes with the same name. Routes are designed to point to one location, filters are designed to filter access to a route, denying clients that don't meet the criteria (not authed, bad csrf token, not enough permissions etc).

I'd be asking yourself if you really need your example route to point to two different places depending on user input, based on my experience so far the answer is probably no.

Have you considered something like

Route::group( array( 'prefix' => 'admin', 'before' => 'admin' ) function() {
    Route::get( 'admin',   function() { return "admin index";    } );
    Route::get( 'example', function() { return "admin example";  } );
});

Route::group( array( 'prefix' => 'client', 'before' => 'client' ), function() {
    Route::get( 'client',  function() { return "client index";   } );
    Route::get( 'example', function() { return "client example"; } );
});

Then you'd navigate to that via

example.co.uk/admin/example
example.co.uk/client/example

If that doesn't work for you and you really need the routes to point to different places, the two options I'd be considering are

  1. Using if statements like you suggested in your first post
  2. Handling it within your controller

Controller Example:

function MyControllerFunction() {
    $user = Auth::user();
    if ( is_null( $user ) ) {
        HandleUserNotAuthed();
    }
    if( Auth::user()->isAdmin ) {
        HandleAdminCodeHere();
    } else {
        HandleClientCodeHere();
    }
}

Routes Example:

$user = Auth::user();
if( ! ( is_null( $user ) ) ) {
    if( $user->isAdmin ) {
        Route::get( 'admin',   function() { return "admin index";    } );
        Route::get( 'example', function() { return "admin example";  } );
    } else {
        Route::get( 'client',  function() { return "client index";   } );
        Route::get( 'example', function() { return "client example"; } );
    }
}

As you can tell, those last 2 examples are very messy and I wouldn't recommend it unless you absolutely have to have the same URL. Look at your application and figure out if you can use different routes and if you can, do that (:

0
votes

Laravel saves are routes with the url as unique index. That means you can't have two routes with same url unless your using an if/else.

I suggest you to create another filter that checks if the user is an admin or client and then add the shared Route to a new group.

Filters

Route::filter('admin', function()
{
    if (Auth::guest() || Auth::user()->type !== 1) return Redirect::to('/');
});

Route::filter('client', function()
{
    if (Auth::guest() || Auth::user()->type != 2) return Redirect::to('/');
});

Route::filter('admin_or_client', function()
{
    if (Auth::guest() || ! in_array(Auth::user()->type, [1, 2])) return Redirect::to('/');
});

Routes

/* Admin */
Route::group(array('before' => 'admin'), function()
{
    Route::get('admin', function(){ return "admin index"; });
});

/* Client */
Route::group(array('before' => 'client'), function()
{
    Route::get('client', function(){ return "client index"; })
});

/* Admin or Client */
Route::group(array('before' => 'admin_or_client'), function()
{
    Route::get('ejemplo', function(){ return "admin or client ejmplo"; });
});