Unequal Items Per Page In Clistview

I have a strange problem with CListView and CActiveDataProvider.

When I’m trying to list items in clistview, in some pages between first and last page, items are less than page size!

I don’t even know where to dig for this problem.

Anyone’s guidance will be appreciated!

It’s been awhile but I believe that because of the way CActiveDataProvider retrieves data it will only count records in the primary table. If your query has a condition which limits the result because of the value of a child table it will do what you are explaining. IMHO, The easiest way to fix this is the create a view in your DB with what you want in it and then use that instead of a complicated Yii query.

krowe is right. Post your criteria code and someone can assist. I had the same problem using a many_many relationship. Also, take a look here - http://www.yiiframework.com/wiki/428/drills-search-by-a-has_many-relation/#hh14

Notice the select, together, and group.

Matt

Here’s the code that I’m working on:

in this I use a class for searching in my website, and this is search function of this class.

relation between product and catalog, product tag is HAS_MANY.




public function search($q) {

	

		/**

		 * base

		 */

		$criteria = new CDbCriteria();

		$criteria->addCondition('t.publish="yes"');

		$criteria->order = 't.creationDate DESC';

		

		

		/**

		 * keyword

		 */

		if ($q['keyword']) {

			$words = array_map('trim', explode(' ', $q['keyword']));

			$criteriaKeyword = new CDbCriteria();

			

			if (is_array($words)) {

				foreach ($words as $word)

				{

					$criteriaKeyword->compare('t.title', $word, true, 'OR');

					$criteriaKeyword->compare('t.description', $word, true, 'OR');

					$criteriaKeyword->compare('catalogs.title', $word, true, 'OR');

					$criteriaKeyword->compare('catalogs.description', $word, true, 'OR');

					$criteriaKeyword->compare('tags.name', $word, true, 'OR');

				}

			}

			

			if ($criteriaKeyword)

			{

				$criteria->with[] = 'catalogs';

				$criteria->with[] = 'tags';

				$criteria->together = true;

				$criteria->mergeWith($criteriaKeyword, true);

			}

		}

		

		

		

		/**

		 * category

		 */

		if ($q['category']) {

			$criteriaCategory = new CDbCriteria();

			$criteriaCategory->compare('productCategories.categoryId', $q['category']);

			if ($criteriaCategory) {

				$criteria->with[] = 'productCategories';

				$criteria->together = true;

				$criteria->mergeWith($criteriaCategory, true);

			}

		}

		

		

		

		/**

		 * language

		 */

		if ($q['language']) {

			$criteriaLanguage = new CDbCriteria();

			$criteriaLanguage->compare('catalog.languageId', $q['language']);

			if ($criteriaLanguage) {

				$criteria->with[] = 'catalogProducts';

				$criteria->with[] = 'catalogProducts.catalog';

				$criteria->together = true;

				$criteria->mergeWith($criteriaLanguage, true);

			}

		}

		return $dataProvider = new CActiveDataProvider('Product', array(

				'criteria'=>$criteria,

				'totalItemCount'=>500,

				'pagination'=>array(

						'pageSize'=>20,

				),


		));

	}



in controller i have just render a view and send this search function as variable to view!

Haven’t tested it but something like this:


public function search($q)

{

	/**

     * base

     */

	$criteria = new CDbCriteria();

	$criteria->addCondition('t.publish="yes"');

	$criteria->order = 't.creationDate DESC';

	// group by Product's id

    $criteria->group = 't.id';

	

	/**

     * keyword

     */

	if ($q['keyword']) 

	{

		$words = array_map('trim', explode(' ', $q['keyword']));

		$criteriaKeyword = new CDbCriteria();

		

		if (is_array($words)) 

		{

			foreach ($words as $word)

			{

				$criteriaKeyword->compare('t.title', $word, true, 'OR');

				$criteriaKeyword->compare('t.description', $word, true, 'OR');

				$criteriaKeyword->compare('catalogs.title', $word, true, 'OR');

				$criteriaKeyword->compare('catalogs.description', $word, true, 'OR');

				$criteriaKeyword->compare('tags.name', $word, true, 'OR');

			}

		}

		

		if ($criteriaKeyword)

		{

			$criteria->with[] = array(

				'catalogs' => array(

					'together' => true,

					'select' => false

				),

				'tags' => array(

					'together' => true,

					'select' => false

				)

			);

			

			$criteria->mergeWith($criteriaKeyword, true);

		}

	}

	

	

	/**

     * category

     */

	if ($q['category']) 

	{

		$criteriaCategory = new CDbCriteria();

		$criteriaCategory->compare('productCategories.categoryId', $q['category']);

		if ($criteriaCategory) 

		{

			$criteria->with[] = array(

				'productCategories' => array(

					'together' => true,

					'select' => false

				)

			);


			$criteria->mergeWith($criteriaCategory, true);

		}

	}

	

	/**

     * language

     */

	if ($q['language']) 

	{

		$criteriaLanguage = new CDbCriteria();

		$criteriaLanguage->compare('catalog.languageId', $q['language']);

		if ($criteriaLanguage) 

		{

			$criteria->with[] = array(

				'catalogProducts' => array(

					'together' => true,

					'select' => false

				),

				'catalogProducts.catalog' => array(

					'together' => true,

					'select' => false

				)

			);

			

			$criteria->mergeWith($criteriaLanguage, true);

		}

	}

	

	return $dataProvider = new CActiveDataProvider('Product', array(

		'criteria'=>$criteria,

		'totalItemCount'=>500,

		'pagination'=>array(

			'pageSize'=>20,

		),


	));

}

Matt