问题
Goal: I want to make route filter in Laravel 4 using
Route::group
andRoute::filter
Description
I have 2 types of user :
- Internal
- Distributor
For, Internal
, I have 2 groups:
- admin
- regular
For Distributor
, I have 4 groups:
- gold
- silver
- bronze
- oem
Eligible Route
OEM Distributor are eligible for only 5 routes.
Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController@show'));
Route::get('distributors/{id}/edit', 'DistributorController@edit');
Route::put('distributors/{id}/update', array('as'=>'distributors.update', 'uses'=>'DistributorController@update'));
Route::get('catalog_downloads','CatalogDownloadController@index');
Route::get('catalog_downloads/{id}/download','CatalogDownloadController@file_download');
Regular Distributor are eligible for 8 routes.
Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController@show'));
Route::get('distributors/{id}/edit', 'DistributorController@edit');
Route::put('distributors/{id}/update', array('as'=>'distributors.update', 'uses'=>'DistributorController@update'));
Route::get('catalog_downloads','CatalogDownloadController@index');
Route::get('catalog_downloads/{id}/download','CatalogDownloadController@file_download');
Route::get('marketing_materials','MarketingMaterialController@index');
Route::get('marketing_materials/{id}/download/thumb_path','MarketingMaterialController@thumb_download');
Route::get('marketing_materials/{id}/download/media_path','MarketingMaterialController@media_download');
Code
- filters.php
- routes.php.
Questions
- Can someone please help me or at least direct me to the right direction ?
回答1:
First off: It's not possibble to declare a route that results in the same URL twice. Whether it's in a group or not. (Well if you have a group with prefix
it's possible because a prefix changes to URL of the route)
You have to solve this problem by intelligent filtering
This is the simplest solution I've come up with:
Route::filter('distributor', function(){
$user = Auth::user();
if($user->type == "Distributor"){
return true;
}
if (Request::ajax()){
return Response::make('Unauthorized', 404);
}
return View::make('errors.404_auth');
});
Route::filter('distributor.regular', function(){
$user = Auth::user();
if($user->type == "Distributor"){
if($user->distributor()->type != 'OEM'){
return true;
}
}
if (Request::ajax()){
return Response::make('Unauthorized', 404);
}
return View::make('errors.404_auth');
});
The distributor
filter checks just if the user is of type Distributor
. The second filter, distributor.regular
, checks if the distributor is not an OEM. (If you're wondering, the dot in distributor.regular
has no special function or deeper meaning. I just like to write it like that)
Route::group(['before' => 'distributor'], function(){
Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController@show'));
Route::get('distributors/{id}/edit', 'DistributorController@edit');
Route::put('distributors/{id}/update', array('as'=>'distributors.update', 'uses'=>'DistributorController@update'));
Route::get('catalog_downloads','CatalogDownloadController@index');
Route::get('catalog_downloads/{id}/download','CatalogDownloadController@file_download');
Route::group(['before' => 'distributor.regular'], function(){
Route::get('catalog_downloads', 'CatalogDownloadController@index');
Route::get('catalog_downloads/{id}/download', 'CatalogDownloadController@file_download');
Route::get('marketing_materials', 'MarketingMaterialController@index');
Route::get('marketing_materials/{id}/download/thumb_path', 'MarketingMaterialController@thumb_download');
Route::get('marketing_materials/{id}/download/media_path', 'MarketingMaterialController@media_download');
});
});
This should already work with the use-cases you posted. However we can make the filters more flexible and also reduce redundant code.
function makeError404(){
if (Request::ajax()){
return Response::make('Unauthorized', 404);
}
return View::make('errors.404_auth');
}
Route::filter('distributor', function(){
$user = Auth::user();
if($user->type == "Distributor"){
return true;
}
return makeError404();
});
Route::filter('distributor.group', function($route, $request, $value){
$groups = explode(';', $value);
$user = Auth::user();
if($user->type == "Distributor"){
if(in_array($user->distributor()->type, $groups)){
return true;
}
}
return makeError404();
});
Now we can dynamically specify in which group the user has to be...
Route::group(['before' => 'distributor'], function(){
// distributor routes
Route::group(['before' => 'distributor.group:gold;silver;bronze'], function(){
// regular routes
});
});
回答2:
You can follow a path like this
class UserController extends BaseController {
/**
* Instantiate a new UserController instance.
*/
public function __construct()
{
$this->beforeFilter('employee', array('only' => 'index'));
}
}
来源:https://stackoverflow.com/questions/27173234/how-to-make-a-route-filters-base-on-user-type-in-laravel-4