Yii 1.1: CGridView / CUrlManager / Breaks filtering

I have enabled "beautiful urls" by configuring the CUrlManager like this:




'urlManager'=>array(

		'urlFormat'=>'path',

		'showScriptName'=>false,

		'rules'=>array(

				'<controller:\w+>/<id:\d+>'=>'<controller>/view',

				'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',

				'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',

				'browserconfig.xml'=>'microsoft/browserconfig',

				''=>'',

		),

),



Unfortunately I have quite some issues with filtering since I enabled it, and I now analysed why.

Basically, after applying a few filter updates, the url generated by CGridView looks like this:




http://www.example.com/controller/action/param1/valueA?param1=valueB



The "GET" parameter having "valueB" is the most recently requested filter.

Unfortunately, the CUrlManager will decode the ‘param/valueA’ part and applies ‘valueA’ to param1.

So, IMHO this is not the right behavior: the actual GET values should have precedence over the values encoded in the path. So I think that the algorithm should be to convert the path "parameters" to an array and "merge" the actual $_GET value with it so that the provided $_GET values have precedence.

The CUrlManager does the following for the default parameters (i.e., it test if the $_GET value exists); something similar in spirit should be applied to the path parameters.


foreach($this->defaultParams as $name=>$value)

{

	if(!isset($_GET[$name]))

		$_REQUEST[$name]=$_GET[$name]=$value;

}

I looked if other people had the same issue and I found a report dating back to 2010:

https://code.google.com/p/yii/issues/detail?id=1325

Unfortunately that is a “Wont-fix”, but I do not understand the rational compared to my use. I have no ‘*’, so I can not remove it.

I’ld think that if the CUrlManager breaks the CGridView filterering, that this is something abnormal in the framework.

As my attention is a bit more focussed on this behavior, I noticed that the "incompatibliity" with the CUrlManager is actually induced when a CPagination is clicked.

The CPagination links are created in PHP and they are path encoded if the CUrlManager is configured to do so. Hence the filter parameters are path encoded once the page link is clicked.

Subsequent filter changes suffer from the precedence in of the path encoded parameters

It looks like it is better to have CPagination append/update the pageVar to the current url rather than constructing the Url through the Controller’s createUrl from the route and the current params.

Reminder of the code creating the Url in CPagination:


	public function createPageUrl($controller,$page)

	{

		$params=$this->params===null ? $_GET : $this->params;

		if($page>0) // page 0 is the default

			$params[$this->pageVar]=$page+1;

		else

			unset($params[$this->pageVar]);

		return $controller->createUrl($this->route,$params);

	}

Changing CPagination would not "fix" CUrlManager, but would at least avoid the side effect which seems to be coming from CPagination in most cases.

The ‘sort’ links in the CGridView are also affected.

Another incompatibility appeared: when entering a slash ("/") as search value, the Url is also badly formed as the slash is not encoded.

This seems to occur in the pagination links.