Gridview CLinkpager and urlFormat =>path

I have done a few applications with Yii now but this is the first time I am using urlFormat set to path. The reason I have is set this way is because my current application will be replacing something I did a few years ago that was programmed in CodeIgniter.

in my config file I define the urlManager like this


		// uncomment the following to enable URLs in path-format

		

		'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>',

                                'home'=>'site/index',

                                'programs/brief'=>'programs/index',

			),

		),

It’s basically the default setup for this component.

I am using CDataprovider and displaying the results in a view using CGridView.

This is my controller code, pretty basic


	public function actionIndex()

	{

            $today= getdate();

	        $currentYear = $today['year'];


            $dataProvider=new CActiveDataProvider('Event', array(

			'pagination'=>array(

				'pageSize'=>16,

			),

                'criteria'=>array(

                            'condition'=>'year(EventStartDate)>=:Year AND event_type_id=:TYPE',

                            'params'=>array(':Year'=>$currentYear,':TYPE'=>1),

                            'order'=>'EventStartdate ASC',

                        ),


		));

            $this->render('index',array(

                'dataProvider'=>$dataProvider,

            ));

	}



This is my view code, again, very basic.


<div class="main">


    <?php $this->widget('zii.widgets.grid.CGridView', array(

	'dataProvider'=>$dataProvider,

	'columns'=>array(

		'EventName',

		'EventStartdate',

		'EventCost',

		array(

			'class'=>'CButtonColumn',

		),

	),

 

)); ?>




</div>

The problem is the pager doesn’t work and sorting doesn’t work. I’m not sure why the sorting doesn’t work but the pager is creating incorrect URL’s.

With urlManager commented out (default setup) I get URL’s like this.


http://DomainName/index.php?r=programs/index&Event_page=2

With urlManager set ‘urlFormat’=>‘path’ I get URL’s like this


http://DomainName/programs/index?%2Fprograms%2Findex=&Event_page=2

The controller and action are output twice!

I also have the following code in .htaccess


<IfModule mod_rewrite.c>


   RewriteEngine On


   RewriteBase /


   RewriteCond %{REQUEST_FILENAME} !-f


   RewriteCond %{REQUEST_FILENAME} !-d


   RewriteRule ^(.*)$ index.php?/$1 [L]


</IfModule>



Any help would be much appreciated.

Thanks,

doodle

While I don’t think it will solve your problem: you should change the order of the rules for the urlManager.

The rules are ‘tested’ in the order given in your config. A request for ‘programs/brief’ for example will be matched by the second rule instead of the last (and an error will arise that your programController does not have a ‘brief’ Action).

Put the most specific rules (the last two) first and try again.




		

		'urlManager'=>array(

			'urlFormat'=>'path',

                        'showScriptName'=>false,

			'rules'=>array(

                                'home'=>'site/index',

                                'programs/brief'=>'programs/index',

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

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

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

			),

		),

                

@nicocin

Thanks for your advise, that make perfect sense and it is obvious once you point it out ::)

Unfortunately it does not solve the problem with the CLinkPager

I now I get


http://DomainName/programs/brief?/programs/brief=&Event_page=3

If I remove my own rules '‘programs/brief’=>‘programs/index’

I get


http://DomainName/programs/index?/programs/index=&Event_page=3

So the route and action are being processes as $_GET parameters.

:(

I can’t spend a lot of time on this but I will post if I find a solution, in the mean time if anyone else has any idea I would be grateful.

@qiang is this a bug? or am I doing something wrong?

doodle

CPagination (by default) uses the


createUrl($route, $params)

method of the current controller. You didn’t override the default implementation of this method in your controller?

You could override the createUrl method in your controller to print out its parameters. That should give you an idea about where something goes wrong.

Thanks, I appreciate your input and I will let you know if I solve this.

doodle

I got a similar problem. I have only one rule in urlManager config, which is


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

.

With urlManager turned off, the link for the 2nd page of a grid view is


http://localhost/index.php?r=product/list&Product_page=2

However, with urlManager turned on, the link is changed to


http://localhost/product/list/product/list//Product_page/2

.

You can see product/list/ is repeated and there are two slashes after it. This URL gives a 404 error.

I guess this usage is very common. Nobody encountered the same problem?

Maybe this example will help. This will create ‘/example/all’ & ‘/example/all/page/2’ -kind of urls with pagination.

config/main.php




		'urlManager' => array(

			'showScriptName' => false,

			'urlFormat'=>'path',

			'rules'=>array(

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

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

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

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

			),

		),



Example controller:




	public function actionAll()

	{


		$criteria=new CDbCriteria(array(

			// Add a condition

			'condition'=>'id>0',

			'order'=>'created DESC',

		));


		$dataProvider=new CActiveDataProvider('Example', array(

			'pagination'=>array(

				'pageSize'=>Yii::app()->params['postsPerPage'],

				'pageVar'=> 'page',


			),

			'criteria'=>$criteria,

		));


		$this->render('index',array(

			'dataProvider'=>$dataProvider,

		));


	}



Index view:




<?php $this->widget('zii.widgets.CListView', array(

	'dataProvider'=>$dataProvider,

	'itemView'=>'_view',

	'template'=>"{summary}\n{items}\n{pager}",

	'ajaxUpdate' => false,

)); ?>



Hi,

As for pagination I have solved the problem by adding params as follows:


pagination->params=>array('param1'=>$param1,'param2'=>$param2)

or


pagination->params=>array()

But as for sorting columns, the problem of double "controller/action/controller/action" is still exists…

I have tried many combinations of ‘rules’ without success.

Has anyone have the answer?

Fixed by adding ‘sort’ in search() function:


return new CActiveDataProvider(get_class($this), array(

  'criteria'=>$criteria, 

  'pagination'=>array('params'=>$params, 'pageVar'=>'page', 'pageSize'=>$pageSize),

  'sort'=>array('params'=>$params, 'sortVar'=>'sort'),

));

The $params is the array of model attributes that your form contains. Could be as follows:


$params=array(

  'Message'=>array(

    'msg_user_id'=>$this->msg_user_id, 

    'msg_datetime'=>$this->msg_datetime

  )

);

Unfortunately it is needed to make many changes all over the application after switching urlFormat to ‘path’…

Hope it helps.

Got stuck on this as well; it turned out the rewrite rules in httpd.conf were wrong so it was not really a Yii issue.

So, double check the rewrite settings in httpd.conf…