问题
Goal: I want to make route filter in Laravel 4 using
Route::groupandRoute::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