-
Notifications
You must be signed in to change notification settings - Fork 11.5k
Description
Either i'm missing something or something similar is not possible:
example routes:
domain.com/clientApp/client1
domain.com/clientApp/client2
domain.com/clientApp/client1/contact
domain.com/clientApp/client1/products/007
the goal:
to avoid the need to specify my first parameter in every action-method in all my controllers and allowing the constructor to prepare stuff needed on every request within the clientApp routes. This implementation would seem the most clean one to me, but there is an alternative at the bottom.
Clean:
example route defintions
Route::bind('ClientApp', function($value, $route){
return ClientApp::where('name', $value)->first();
});
/**
* Note the {{ClientApp}} notation:
* my suggestion to make this parameter (or bound model)
* to be injected into the controller constructor instead of being passed to action
* methods as the first parameter
*/
Route::group(array('prefix' => 'clientApp/{{ClientApp}}'), function(){
Route::controller('products','ClientApp\ProductsController');
Route::controller('','ClientApp\HomeController');
});
example controller
namespace ClientApp;
use BaseController as Controller;
/**
* ClientApp BaseController
*/
class BaseController extends Controller
{
protected $app;
public function __construct(ClientApp $app){
parent::__construct();
$this->app = $app;
//do a bunch of stuff like setting layout files depending on the $app,
//or loading correct modules specific to the $app
}
}
namespace ClientApp;
/**
* ClientApp HomeController
*/
class HomeController extends BaseController
{
public function getIndex(){
}
public function getContact(){
}
}
namespace ClientApp;
/**
* ClientApp ProductsController
*/
class ProductsController extends BaseController
{
public function getIndex($productList){
}
}
Alternative: half solution
allow for routes to match a pattern without injecting the pattern as a parameter into controller action methods.
Route::group(array('prefix' => 'clientApp/:ClientApp:'), function(){
Route::controller('products', 'ClientApp\ProductsController');
Route::controller('','ClientApp\HomeController');
});
This would be the same as a regular {parameter}, but simply not pass it to the controller methods, again {{parameter}} could be used instead of :parameter: as suggested in my first solution.
now i could use IoC dependency injection manually to do layout and other logics in my controller constructor.
Currently this is what is possible:
/*
* BaseController
*/
namespace ClientApp;
use Request;
use BaseController as Controller;
class BaseController extends Controller{
/**
* Use dependency injection and manally search for parameter
*/
public function __construct(ClientApp $app){
$this->app = $app->where('name', Request::segment(2))->first();
$this->setup();
parent::__construct();
}
// OR
/**
* Helper init function that uses first parameter from every action-method
*/
protected function _init($firstParameter){
$this->app = $firstParameter //was bound using Route::bind('ClientApp', closure returning model based on name)
$this->setup();
}
protected function setup(){
//setup layout for this clientApp
//load user data for this clientApp
}
}
/*
* HomeController
*/
namespace ClientApp;
class HomeController extends BaseController{
public function getIndex($firstParameter){ //shouldn't need to pass this to the method
$this->_init($firstParameter); //should only be used when init implementation used
//action specifics
}
public function getContact($firstParameter){ //shouldn't need to pass this to the method
$this->_init($firstParameter); //should only be used when init implementation used
//action specifics
}
}
/*
* ProductsController
*/
namespace ClientApp;
class ProductsController extends BaseController{
public function getIndex($firstParameter, $productList){ //should only need $productList
$this->_init($firstParameter); //should only be used when init implementation used
//action specifics
$products = Product::where('listid', $productList)->where('clientAppId', $this->app->id);
//etc...
}
}
The thought of needing to repeat my parameter in every action, and call that same _init() helper method in every action makes me shiver.
I'm sorry if this doesn't make any sense, i've tried my best to keep things clean and simple. Feel free to ask more info if my intentions would be unclear.
This feature would, as i see it, allow for even more complex routes while keeping things DRY.
Regards,
Thomas