I feel the need to share today, so here it is:
In the table where you store the games, add a new column, call it nice_url(the idea is to store the nice url of the game here) and unique INDEX IT.
How you will generate the nice url is up to you, also, i suggest you use dashes(-) instead of underscore in the url because google likes that more.
So let’s say you save a game and the nice_url column of the game is: my-super-duper-game.
Now, having this set, it’s time to work with the url manager, to make it work with our nice url format.
First thing we need to do is to create a url rule class:
// protected/components/MyUrlRule.php
class MyUrlRule extends CBaseUrlRule
{
public $connectionID = 'db';
public function createUrl($manager,$route,$params,$ampersand)
{
if($route==='game/index')
{
if (isset($params['nice_url']))
return $params['nice_url'];
}
return false; // this rule does not apply
}
public function parseUrl($manager,$request,$pathInfo,$rawPathInfo)
{
if(preg_match('%^[a-z0-9\-]+$%', $pathInfo, $matches))
{
$nice_url=$matches[0];
$command=Yii::app()->{$this->connectionID}->createCommand();
$result=$command->select('nice_url')->from('{{games}}');
$result->where('nice_url=:nice_url', array(':nice_url'=>$nice_url));
$result = $result->queryRow();
if(!empty($result)&&$result['nice_url']===$nice_url)
{
$_GET['nice_url']=$result['nice_url'];
return 'game/index';
}
}
return false; // this rule does not apply
}
}
Now that we have the url rule class, let’s use it in the url manager component
// protected/config/main.php
'urlManager'=>array(
'rules' => array(
// all you existing rules here, the MyUrlRule class will be the last one.
array(
'class' => 'application.components.MyUrlRule',
'connectionID' => 'db',
),
),
),
NOTE:
Now, when somebody access http://www.your-domain.com/contact for example, if you have a controller or module named contact, it will match that one so you don’t have to worry about breaking existing rules.
If you don’t have a controller/module named contact, then it will try your “MyUrlRule” class and look into the games table to see if for some reason you have a game called contact. if you don’t have, then it will throw a 404 error.
Back to our example, accessing http://www.your-domain.com/my-super-duper-game will reach your new url rule class in the url manager and the slug "my-super-duper-game" will be matched against the nice_url column from the database. If it will find it, it will forward the request to your game controller, which will process it.
The game controller needs to look like:
class GameController extends CController{
public function actionIndex($nice_url)
{
$model=Game::model()->findByAttributes(array('nice_url'=>$nice_url));
echo $nice_url;//will show "my-super-duper-game";
}
}
As you see, in your controller, based on the $nice_url var you can load your game model and use it further
Well, that’s it
@andy_s - You did it again