UrlManager rules

Is it possible to modify the UrlManager rules during the init or preinit stage of loading a module?  I'm trying to keep my modules as self contained as possible, and would like to be able to modify routing rules from within the module itself.

I'm currently trying with the following with no luck, I know it's a valid rule because adding it to the application config works fine.



	public function preinit() {


		Yii::app()->urlManager->rules['admin/pages/add'] = 'admin/pages/default/add'; 


	}

Any help is appreciated, thanks!

preinit() is too early because at this time, core components like urlManager has not been loaded yet. You may try by overriding processRequest().



public function processRequest()


{


      $this->urlManager->rules=$newRules;


      parent::processRequest();


}


Is this correct for overriding the rules inside a module? processRequest never seems to get called.

I was talking about overriding CWebApplication.

Putting the code in module is inappropriate because by that time, the request is already resolved and thus your rules won't be used.

So there is no way to modify routing rules from within a module currently?  Maybe even cheat a little somehow before a controller within a module is called, and call it manually based on the requested route?

Yes, I agree. It would be great to handle something like this:

modules can define their own rules, and by running the application, all rules of enabled modules would be merged with rules defined in protected/config/main.php, which means that rules configuration of a module, stays in module itself, but is always available for the whole application.

Maybe something like described here: http://www.yiiframew…oc/cookbook/32/ could be useful, but currently I’ve got no idea how to get this done.

Ok, I've tried a little bit around, and I've got a working solution.

You can create a custom class and tell the urlManager (in protected/config/main.php) to use this class:

'urlManager'  => array(

  'class' => 'application.class.UrlManager',

  'urlFormat' => 'path',

  'showScriptName' => false,

  'rules' => array(

    'kontakt' => 'site/contact',

  )

),

Now, in your UrlManager class, you can overwrite the setRules function which makes the UrlManager class looks something like this:

class UrlManager extends CUrlManager

{

public function setRules($arrRule)


{





  $arrModule = Yii::app()->modules;


  $arrModule = (!is_array($arrModule)) ? array() : $arrModule;





  foreach ($arrModule as $strModule => $arrItem)


  {

            $strFile = Yii::app()->basePath.'/modules/'.$strModule.'/config/rules.php';

    if (file_exists($strFile))


    {

        $arrRule = CMap::mergeArray(

          $arrRule,

          require($strFile)

        );

    }


  }





  parent::setRules($arrRule);


}

}

this setRules function looks for all enabled modules, and merges (if existing) the "rules.php" from config dir of module with the given array of rules (these ones, defined in your main config file).

I've tested this with two modules, and it works.

EDIT:

Updated Yii to version 1.0.5 and it seem, like the above posted solution doesn't work with the new release (only with 1.0.4).