I have Yii app with an external parameter “type”, it can be: “basic”, “advanced”, “maximal”. And all I need to do is to launch different “versions” of controllers, depending on parameter. That is how I’m trying to achieve this, I have the following structure:
AdvancedSiteController class is child of BasicSiteController and MaximalSiteController is child of AdvancedSiteController.
I want to pass different actions to appropriate controllers(e.g. $type = “maximal”, then actionIndex() must be called from MaximalSiteController.php). But I don’t know for sure how to implement this, maybe SiteController should be an interface or abstract class? But even if so, then how to go further?
is following folder structure is acceptable to you?
controllers
.../basic
…SiteController.php
…Other controller files.
.../advanced
…SiteController.php
…Other controller files.
.../maximal
…SiteController.php
…Other controller files.
I do not think they are going to conflict, as they are not pre imported or autoloaded.
If this is the situation
Now I can do the following.
I am going to create an application behavior.
components/ApplicationBehavior.php
class ApplicationBehavior extends CBehavior
{
private $_owner;
public function events()
{
return array(
'onBeginRequest'=>'assignControllers',
);
}
public function assignControllers()
{ $label="";
$owner=$this->getOwner();
if(something is true) //apply your logic
$label="maximal";
if(someotherthing is true)
$label="advanced";
else $label="basic";
$owner->controllerPath=$owner->getBasePath().DIRECTORY_SEPARATOR.'controllers'.DIRECTORY_SEPARATOR.$label;
}
Now I am going to attach this behavior to main application.
Things become difficult if we want to implement inheritance basic->advanced->maximal.
Then we have to organise the things in the following way.
controllers/basic/BaseSiteController.php
class BaseSiteController extends Controller
{
...........................................
}
controllers/advanced/AdvancedSiteController.php
Yii::import("application.controllers.basic.BaseSiteController");
class AdvancedSiteController extends BaseSiteController
{
...............................................................
}
controllers/maximal/MaximalSiteController.php
Yii::import("application.controllers.advanced.AdvancedSiteController");
class MaximalSiteController extends AdvancedSiteController
{
...............................................................
}
class ApplicationBehavior extends CBehavior
{
private $_owner;
public function events()
{
return array(
'onBeginRequest'=>'assignControllers',
);
}
public function assignControllers()
{
$owner=$this->getOwner();
if(something is true) //apply your logic
{
$owner->controllerMap=array(
"site"=>array(
"class"=>"application.controllers.maximal.MaximalSiteController",
),
//you can declare controller id for other Controller classes as well.
);
}
if(someOtherThing is true)
{
$owner->controllerMap=array(
"site"=>array(
"class"=>"application.controllers.advanced.AdvancedSiteController",
),
);
}
else
{
$owner->controllerMap=array(
"site"=>array(
"class"=>"application.controllers.basic.BasicSiteController",
),
);
}
}
The problem here is we have explicitely declare controller id for each controller class.