Supporting Legacy CControllers

I’ve written an iPhone app that talks to my database through the web using CControllers to perform actions. Since I’m rendering the view on the iPhone, I simply process incoming JSON requests and send responses from the controller’s actions.

In a recent iteration of the iPhone app I made changes to the controllers that are not backwards compatible with my previous version. That wouldn’t be a big deal except I can’t control (nor predict) when Apple will release my new version to the app store. For this iteration it is also necessary that the updated server code be online when the app is released. That means my controller will need to support both the legacy and updated actions.

I did a little searching and inheritance seemed like it might be a good solution. My plan was to create two classes: CurrentController and LegacyController. CurrentController would extend LegacyController with each containing the current and legacy versions of my actions respectively. I would then implement a isLegacyConnection() routine in CurrentController that would call the parent routines if a legacy connection was detected. With this system, each time I do an app update I push the previous version’s code from CurrentController to LegacyController.

The solution started getting messy once I went to implement it, however. I didn’t realise I couldn’t place my LegacyController in the controllers folder since it’s not in the include path. Now I’m not quite sure where to place it that would make sense from an organizational standpoint. Even after settling on a path I’m not keen on, I can’t figure out how to call an action from the parent LegacyController.

At this point I’m not so sure about this solution. Any suggestions would be appreciated.

You can put LegacyController in the controllers file, or anywhere you like.

To add a path to the auto-include path, simple add it to the import option in the config file, example:




	'import'=>array(

		'application.models.*',

		'application.controllers.*', //see

		//...

	),



You can call an inherited method (from within a child class) like this:




parent::parentMethod()


parent::actionXXX() //it follows you can call the actions like this too



Thanks jonah. That got me sorted out. After posting I realised I might deprecate actions in future versions so I created a filter to test the app version. Posting below should anyone else be looking to do the same.




public $legacyVersion=0.3;


public function filters()

{

	return array(

		'accessControl', // perform access control for CRUD operations

		'appVersion',

	);

}


public function filterAppVersion($filterChain)

{

	$this->json = CJSON::decode(file_get_contents( "php://input" ));

	if($this->json['appVersion'] == $this->legacyVersion){

		$actionId="action".ucfirst($this->action->id);

		parent::$actionId();

	}

	else

		$filterChain->run();

}