mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-10-31 10:39:59 +08:00 
			
		
		
		
	Fix #20175: Fix bad result for pagination when used with GridView
This commit is contained in:
		| @ -8,7 +8,6 @@ | ||||
| namespace yii\build\controllers; | ||||
|  | ||||
| use DirectoryIterator; | ||||
| use Yii; | ||||
| use yii\console\Controller; | ||||
| use yii\helpers\Html; | ||||
|  | ||||
|  | ||||
| @ -4,7 +4,7 @@ Yii Framework 2 Change Log | ||||
| 2.0.51 under development | ||||
| ------------------------ | ||||
|  | ||||
| - no changes in this release. | ||||
| - Bug #20175: Fix bad result for pagination when used with GridView (@lav45) | ||||
|  | ||||
|  | ||||
| 2.0.50 May 30, 2024 | ||||
|  | ||||
| @ -7,8 +7,6 @@ | ||||
|  | ||||
| namespace yii\base; | ||||
|  | ||||
| use Yii; | ||||
|  | ||||
| /** | ||||
|  * ErrorException represents a PHP error. | ||||
|  * | ||||
|  | ||||
| @ -7,7 +7,6 @@ | ||||
|  | ||||
| namespace yii\base; | ||||
|  | ||||
| use Yii; | ||||
| use yii\helpers\StringHelper; | ||||
|  | ||||
| /** | ||||
|  | ||||
| @ -110,7 +110,6 @@ class ActiveDataProvider extends BaseDataProvider | ||||
|         if (($sort = $this->getSort()) !== false) { | ||||
|             $query->addOrderBy($sort->getOrders()); | ||||
|         } | ||||
|  | ||||
|         return $query->all($this->db); | ||||
|     } | ||||
|  | ||||
| @ -128,7 +127,6 @@ class ActiveDataProvider extends BaseDataProvider | ||||
|                     $keys[] = call_user_func($this->key, $model); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return $keys; | ||||
|         } elseif ($this->query instanceof ActiveQueryInterface) { | ||||
|             /* @var $class \yii\db\ActiveRecordInterface */ | ||||
| @ -148,13 +146,13 @@ class ActiveDataProvider extends BaseDataProvider | ||||
|                     $keys[] = $kk; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return $keys; | ||||
|         } | ||||
|  | ||||
|         return array_keys($models); | ||||
|     } | ||||
|  | ||||
|     private $_totalCount = []; | ||||
|  | ||||
|     /** | ||||
|      * {@inheritdoc} | ||||
|      */ | ||||
| @ -163,8 +161,13 @@ class ActiveDataProvider extends BaseDataProvider | ||||
|         if (!$this->query instanceof QueryInterface) { | ||||
|             throw new InvalidConfigException('The "query" property must be an instance of a class that implements the QueryInterface e.g. yii\db\Query or its subclasses.'); | ||||
|         } | ||||
|         $query = clone $this->query; | ||||
|         return (int) $query->limit(-1)->offset(-1)->orderBy([])->count('*', $this->db); | ||||
|         $query = (clone $this->query)->limit(-1)->offset(-1)->orderBy([]); | ||||
|         $key = md5((string)$query); | ||||
|  | ||||
|         if (!array_key_exists($key, $this->_totalCount)) { | ||||
|             $this->_totalCount[$key] = (int)$query->count('*', $this->db); | ||||
|         } | ||||
|         return $this->_totalCount[$key]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @ -196,7 +199,6 @@ class ActiveDataProvider extends BaseDataProvider | ||||
|         if (is_object($this->query)) { | ||||
|             $this->query = clone $this->query; | ||||
|         } | ||||
|  | ||||
|         parent::__clone(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -167,10 +167,10 @@ abstract class BaseDataProvider extends Component implements DataProviderInterfa | ||||
|         if ($this->_pagination === false) { | ||||
|             return $this->getCount(); | ||||
|         } | ||||
|         if ($this->_totalCount === null) { | ||||
|             $this->_totalCount = $this->prepareTotalCount(); | ||||
|         if ($this->_totalCount !== null) { | ||||
|             return (int)$this->_totalCount; | ||||
|         } | ||||
|         return $this->_totalCount; | ||||
|         return $this->prepareTotalCount(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @ -219,7 +219,9 @@ abstract class BaseDataProvider extends Component implements DataProviderInterfa | ||||
|             $value = Yii::createObject(array_merge($config, $value)); | ||||
|         } | ||||
|         if ($value instanceof Pagination) { | ||||
|             $value->totalCount = $this->getTotalCount(); | ||||
|             $value->setTotalCount(function () { | ||||
|                 return $this->getTotalCount(); | ||||
|             }); | ||||
|             $this->_pagination = $value; | ||||
|         } elseif ($value === false) { | ||||
|             $this->_pagination = false; | ||||
|  | ||||
| @ -7,6 +7,7 @@ | ||||
|  | ||||
| namespace yii\data; | ||||
|  | ||||
| use Closure; | ||||
| use Yii; | ||||
| use yii\base\BaseObject; | ||||
| use yii\web\Link; | ||||
| @ -69,6 +70,7 @@ use yii\web\Request; | ||||
|  * @property-read int $pageCount Number of pages. | ||||
|  * @property int $pageSize The number of items per page. If it is less than 1, it means the page size is | ||||
|  * infinite, and thus a single page contains all items. | ||||
|  * @property int $totalCount total number of items. | ||||
|  * | ||||
|  * @author Qiang Xue <qiang.xue@gmail.com> | ||||
|  * @since 2.0 | ||||
| @ -123,10 +125,6 @@ class Pagination extends BaseObject implements Linkable | ||||
|      * number validation. By doing so, [[page]] will return the value indexed by [[pageParam]] in [[params]]. | ||||
|      */ | ||||
|     public $validatePage = true; | ||||
|     /** | ||||
|      * @var int total number of items. | ||||
|      */ | ||||
|     public $totalCount = 0; | ||||
|     /** | ||||
|      * @var int the default page size. This property will be returned by [[pageSize]] when page size | ||||
|      * cannot be determined by [[pageSizeParam]] from [[params]]. | ||||
| @ -143,6 +141,10 @@ class Pagination extends BaseObject implements Linkable | ||||
|      * If it is less than 1, it means the page size is infinite, and thus a single page contains all items. | ||||
|      */ | ||||
|     private $_pageSize; | ||||
|     /** | ||||
|      * @var Closure|int total number of items or closure returning it. | ||||
|      */ | ||||
|     private $_totalCount = 0; | ||||
|  | ||||
|  | ||||
|     /** | ||||
| @ -151,13 +153,11 @@ class Pagination extends BaseObject implements Linkable | ||||
|     public function getPageCount() | ||||
|     { | ||||
|         $pageSize = $this->getPageSize(); | ||||
|         $totalCount = $this->getTotalCount(); | ||||
|         if ($pageSize < 1) { | ||||
|             return $this->totalCount > 0 ? 1 : 0; | ||||
|             return $totalCount > 0 ? 1 : 0; | ||||
|         } | ||||
|  | ||||
|         $totalCount = $this->totalCount < 0 ? 0 : (int) $this->totalCount; | ||||
|  | ||||
|         return (int) (($totalCount + $pageSize - 1) / $pageSize); | ||||
|         return (int) ((max($totalCount, 0) + $pageSize - 1) / $pageSize); | ||||
|     } | ||||
|  | ||||
|     private $_page; | ||||
| @ -173,7 +173,6 @@ class Pagination extends BaseObject implements Linkable | ||||
|             $page = (int) $this->getQueryParam($this->pageParam, 1) - 1; | ||||
|             $this->setPage($page, true); | ||||
|         } | ||||
|  | ||||
|         return $this->_page; | ||||
|     } | ||||
|  | ||||
| @ -221,7 +220,6 @@ class Pagination extends BaseObject implements Linkable | ||||
|                 $this->setPageSize($pageSize, true); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $this->_pageSize; | ||||
|     } | ||||
|  | ||||
| @ -264,7 +262,7 @@ class Pagination extends BaseObject implements Linkable | ||||
|             $request = Yii::$app->getRequest(); | ||||
|             $params = $request instanceof Request ? $request->getQueryParams() : []; | ||||
|         } | ||||
|         if ($page > 0 || $page == 0 && $this->forcePageParam) { | ||||
|         if ($page > 0 || ($page === 0 && $this->forcePageParam)) { | ||||
|             $params[$this->pageParam] = $page + 1; | ||||
|         } else { | ||||
|             unset($params[$this->pageParam]); | ||||
| @ -282,7 +280,6 @@ class Pagination extends BaseObject implements Linkable | ||||
|         if ($absolute) { | ||||
|             return $urlManager->createAbsoluteUrl($params); | ||||
|         } | ||||
|  | ||||
|         return $urlManager->createUrl($params); | ||||
|     } | ||||
|  | ||||
| @ -293,7 +290,6 @@ class Pagination extends BaseObject implements Linkable | ||||
|     public function getOffset() | ||||
|     { | ||||
|         $pageSize = $this->getPageSize(); | ||||
|  | ||||
|         return $pageSize < 1 ? 0 : $this->getPage() * $pageSize; | ||||
|     } | ||||
|  | ||||
| @ -305,7 +301,6 @@ class Pagination extends BaseObject implements Linkable | ||||
|     public function getLimit() | ||||
|     { | ||||
|         $pageSize = $this->getPageSize(); | ||||
|  | ||||
|         return $pageSize < 1 ? -1 : $pageSize; | ||||
|     } | ||||
|  | ||||
| @ -331,7 +326,6 @@ class Pagination extends BaseObject implements Linkable | ||||
|                 $links[self::LINK_NEXT] = $this->createUrl($currentPage + 1, null, $absolute); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $links; | ||||
|     } | ||||
|  | ||||
| @ -348,7 +342,25 @@ class Pagination extends BaseObject implements Linkable | ||||
|             $request = Yii::$app->getRequest(); | ||||
|             $params = $request instanceof Request ? $request->getQueryParams() : []; | ||||
|         } | ||||
|  | ||||
|         return isset($params[$name]) && is_scalar($params[$name]) ? $params[$name] : $defaultValue; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return int total number of items. | ||||
|      */ | ||||
|     public function getTotalCount() | ||||
|     { | ||||
|         if (is_numeric($this->_totalCount)) { | ||||
|             return (int)$this->_totalCount; | ||||
|         } | ||||
|         return (int)call_user_func($this->_totalCount); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Closure|int $count | ||||
|      */ | ||||
|     public function setTotalCount($count) | ||||
|     { | ||||
|         $this->_totalCount = $count; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -7,7 +7,6 @@ | ||||
|  | ||||
| namespace yii\data; | ||||
|  | ||||
| use Yii; | ||||
| use yii\base\InvalidConfigException; | ||||
| use yii\db\Connection; | ||||
| use yii\db\Expression; | ||||
| @ -150,10 +149,8 @@ class SqlDataProvider extends BaseDataProvider | ||||
|                     $keys[] = call_user_func($this->key, $model); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return $keys; | ||||
|         } | ||||
|  | ||||
|         return array_keys($models); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -7,7 +7,6 @@ | ||||
|  | ||||
| namespace yii\db; | ||||
|  | ||||
| use Yii; | ||||
| use yii\base\BaseObject; | ||||
| use yii\helpers\StringHelper; | ||||
|  | ||||
|  | ||||
| @ -7,7 +7,6 @@ | ||||
|  | ||||
| namespace yii\i18n; | ||||
|  | ||||
| use Yii; | ||||
| use yii\base\InvalidConfigException; | ||||
| use yii\caching\CacheInterface; | ||||
| use yii\db\Connection; | ||||
|  | ||||
| @ -7,7 +7,6 @@ | ||||
|  | ||||
| namespace yii\log; | ||||
|  | ||||
| use Yii; | ||||
| use yii\base\InvalidConfigException; | ||||
| use yii\db\Connection; | ||||
| use yii\db\Exception; | ||||
|  | ||||
| @ -7,7 +7,6 @@ | ||||
|  | ||||
| namespace yii\log; | ||||
|  | ||||
| use Yii; | ||||
| use yii\base\Component; | ||||
|  | ||||
| /** | ||||
|  | ||||
| @ -7,7 +7,6 @@ | ||||
|  | ||||
| namespace yii\log; | ||||
|  | ||||
| use Yii; | ||||
| use yii\helpers\VarDumper; | ||||
|  | ||||
| /** | ||||
|  | ||||
| @ -7,7 +7,6 @@ | ||||
|  | ||||
| namespace yii\rbac; | ||||
|  | ||||
| use Yii; | ||||
| use yii\base\BaseObject; | ||||
|  | ||||
| /** | ||||
|  | ||||
| @ -7,7 +7,6 @@ | ||||
|  | ||||
| namespace yii\rest; | ||||
|  | ||||
| use Yii; | ||||
| use yii\base\InvalidConfigException; | ||||
| use yii\db\ActiveRecordInterface; | ||||
| use yii\web\NotFoundHttpException; | ||||
|  | ||||
| @ -7,8 +7,6 @@ | ||||
|  | ||||
| namespace yii\rest; | ||||
|  | ||||
| use Yii; | ||||
|  | ||||
| /** | ||||
|  * ViewAction implements the API endpoint for returning the detailed information about a model. | ||||
|  * | ||||
|  | ||||
| @ -7,7 +7,6 @@ | ||||
|  | ||||
| namespace yii\web; | ||||
|  | ||||
| use Yii; | ||||
| use yii\caching\CacheInterface; | ||||
| use yii\di\Instance; | ||||
|  | ||||
|  | ||||
| @ -7,7 +7,6 @@ | ||||
|  | ||||
| namespace yii\web; | ||||
|  | ||||
| use Yii; | ||||
| use yii\base\BaseObject; | ||||
|  | ||||
| /** | ||||
|  | ||||
| @ -197,4 +197,23 @@ abstract class ActiveDataProviderTest extends DatabaseTestCase | ||||
|  | ||||
|         $this->assertEquals(0, $pagination->getPageCount()); | ||||
|     } | ||||
|  | ||||
|     public function testTotalCountAfterSearch() | ||||
|     { | ||||
|         $query = Order::find(); | ||||
|         $provider = new ActiveDataProvider([ | ||||
|             'query' => $query, | ||||
|             'pagination' => [ | ||||
|                 'pageSize' => 2, | ||||
|             ], | ||||
|         ]); | ||||
|  | ||||
|         $pagination = $provider->getPagination(); | ||||
|         $this->assertEquals(2, $pagination->getPageCount()); | ||||
|         $this->assertEquals(3, $pagination->getTotalCount()); | ||||
|  | ||||
|         $query->andWhere(['customer_id' => 2]); | ||||
|         $this->assertEquals(1, $pagination->getPageCount()); | ||||
|         $this->assertEquals(2, $pagination->getTotalCount()); | ||||
|     } | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Alex
					Alex