Cactivedataprovider And Cactiverecordbehavior

(Yiiframework) #1

I have a behavior attached to a model and it makes the CActiveDataProvide not count properly (it says in the pagination that it has all the records in the database)

From looking around the source code, I think it probably deals with calculateTotalItemCount() but a little stumped on creating a patch (and not too sure if it’s a bug or intended this way).

If it is intended this way I am probably going to just create a custom class that extends CActiveDataProvide to provide a fix for my models but wondering what I should change to make it work properly.

Here is a simplified version of the Behavior:

class MyBehavior extends CActiveRecordBehavior{

	function afterConstruct( $event ){

		$condition = $this->owner->getDbCriteria();

		$condition->compare( $this->owner->getTableAlias() .'.active', 1 );




id active

1 1

2 0

3 1

4 0

So in the Controller:

class TableController extends CController{


		$dataProvider = CActiveDataProvider( 'Table' );

		$this->render( 'index', array( 'dataProvider' => $dataProvider ) );



Expected results: "Displaying 1-2 of 2 result(s)."

Results I am getting: "Displaying 1-2 of 4 result(s)."

Yii Version: 1.1.12

OS: Windows 7 32bit

DB: MySQL 5.5.20

PHP: 5.3.9

Webserver: Apache 2.2.21


The problem occurs because the first query fetching the data has the condition applied, but second has not as scopes and criteria will be reset after a query.

This is expected behavior so you have to adjust your behavior to work as you want it.

Changing criteria in afterContruct is not a good idea as it only works for the first query executed on that object.

Currently have no idea how you could do that transparently without touching models code.

criteria modification in beforeFind() would be one way, but this would still not apply to the count query.

There is a feature request on beforeCount() event on github


Something similar is done here:

(Yiiframework) #4

Yea I had it in the beforeFind before, but I figured I would try it in the afterConstruct when I was testing it to see if I could get something working.

I think beforeFind would be good and I am glad to see some work on getting it implemented.

Thanks for your help :)