Hi guys!
I’m in the painful process to convert a Drupal site on Yii. Here’s the scenario i need help with at the moment:
I need to handle invalid URLs such as http://www.xyz.com/unknownpage.html, http://www.xyz.com/aboutus.html without throwing 404 error. I need to take the request uri from this, lookup into a DB table url_alias, and depending upon that need to forward it either one of some specified controllers such as nodes, terms, users etc…
Below is the Controller::nodeRouter() method for decision logic. Question is what’s the best place to place this conditional logic ? This nodeRouter shall only be triggered if the url/route is invalid but without throwing the 404 exception.
public static function nodeRouter($urlpath=null) {
$urlpath = $urlpath ? $urlpath : Yii::app()->request->pathInfo;
// Handle Root/Home Page
if (empty($urlpath)) {
return;
}
$sqlAlias = "SELECT * FROM ".TBL_URL_ALIASES." WHERE alias='$urlpath'";
$modelAlias = Yii::app()->db->createCommand($sqlAlias)->queryAll();
$modelAlias = isset($modelAlias[0]) ? $modelAlias[0] : array();
if (isset($modelAlias['id'])) {
$route_controller_array = explode("/",$modelAlias['path']);
$route_controller = $route_controller_array[0]; returns one of these: nodes, terms, users
$route_id = $route_controller_array[1]; returns records pk id i.e. 44 or something
switch ($route_controller) {
case 'nodes':
$_GET['id'] = $route_id;
Yii::app()->runController('/cms/nodes/view');
break;
case 'terms':
$_GET['id'] = $route_id;
Yii::app()->runController('/cms/terms/view');
break;
case 'users':
break;
default:
break;
}
}
// If not routed any where means the Request is invalid
return false;
}
I tried placing Controller::nodeRouter() in the following places:
Placement 1:
============
In Controller::init() - Here i get an infinite loop as Controller::init() triggers each time after Controller::forward() is fired.
Placement 2:
============
In SiteController::actionError() - All works fine here except the issue that the desired pages are rendered but with a 404 Exception. I understand this exception comes from CWebApplication::runController(). This ugly solution will create major SEO issues for the site and i can’t go with that. Neither do i want to hack the core.
How exactly shall i get around with this issue. Appreciate if i can get some help.
Thanks,
Raheel