diff --git a/framework/web/Pagination.php b/framework/web/Pagination.php
index 8fd7b51..72b1e09 100644
--- a/framework/web/Pagination.php
+++ b/framework/web/Pagination.php
@@ -7,59 +7,57 @@
namespace yii\web;
+use Yii;
+
/**
- * Pagination represents information relevant to pagination.
+ * Pagination represents information relevant to pagination of data items.
*
- * When data needs to be rendered in multiple pages, we can use Pagination to
- * represent information such as {@link getItemCount total item count},
- * {@link getPageSize page size}, {@link getCurrentPage current page}, etc.
- * These information can be passed to {@link CBasePager pagers} to render
- * pagination buttons or links.
+ * When data needs to be rendered in multiple pages, Pagination can be used to
+ * represent information such as [[itemCount|total item count]], [[pageSize|page size]],
+ * [[page|current page]], etc. These information can be passed to [[yii\web\widgets\Pager|pagers]]
+ * to render pagination buttons or links.
*
- * Example:
+ * The following example shows how to create a pagination object and feed it
+ * to a pager.
*
* Controller action:
*
* ~~~
* function actionIndex()
* {
- * $criteria=new CDbCriteria();
- * $count=Article::model()->count($criteria);
- * $pages=new Pagination($count);
- *
- * // results per page
- * $pages->pageSize=10;
- * $pages->applyLimit($criteria);
- * $models=Article::model()->findAll($criteria);
+ * $query = Article::find()->where(array('status' => 1));
+ * $countQuery = clone $query;
+ * $pages = new Pagination($countQuery->count());
+ * $models = $query->offset($pages->offset)
+ * ->limit($pages->limit)
+ * ->all();
*
* $this->render('index', array(
- * 'models' => $models,
+ * 'models' => $models,
* 'pages' => $pages
* ));
* }
* ~~~
*
* View:
- *
+ *
+ * ~~~
*
- * // display a model
+ * ...display a model...
*
*
* // display pagination
- * widget('CLinkPager', array(
+ * widget('yii\web\widgets\LinkPager', array(
* 'pages' => $pages,
* )) ?>
- *
+ * ~~~
*
- * @property integer $pageSize Number of items in each page. Defaults to 10.
- * @property integer $itemCount Total number of items. Defaults to 0.
* @property integer $pageCount Number of pages.
- * @property integer $currentPage The zero-based index of the current page. Defaults to 0.
+ * @property integer $page The zero-based index of the current page.
* @property integer $offset The offset of the data. This may be used to set the
* OFFSET value for a SQL statement for fetching the current page of data.
* @property integer $limit The limit of the data. This may be used to set the
* LIMIT value for a SQL statement for fetching the current page of data.
- * This returns the same value as {@link pageSize}.
*
* @author Qiang Xue
* @since 2.0
@@ -67,82 +65,53 @@ namespace yii\web;
class Pagination extends \yii\base\Object
{
/**
- * The default page size.
- */
- const DEFAULT_PAGE_SIZE = 10;
- /**
* @var string name of the GET variable storing the current page index. Defaults to 'page'.
*/
public $pageVar = 'page';
/**
- * @var string the route (controller ID and action ID) for displaying the paged contents.
- * Defaults to empty string, meaning using the current route.
- */
- public $route = '';
- /**
- * @var array of parameters (name=>value) that should be used instead of GET when generating pagination URLs.
- * Defaults to null, meaning using the currently available GET parameters.
+ * @var boolean whether to always have the page parameter in the URL created by [[createUrl()]].
+ * If false and [[page]] is 0, the page parameter will not be put in the URL.
*/
- public $params;
+ public $forcePageVar = false;
/**
- * @var boolean whether to ensure {@link currentPage} is returning a valid page number.
- * When this property is true, the value returned by {@link currentPage} will always be between
- * 0 and ({@link pageCount}-1). Because {@link pageCount} relies on the correct value of {@link itemCount},
- * it means you must have knowledge about the total number of data items when you want to access {@link currentPage}.
- * This is fine for SQL-based queries, but may not be feasible for other kinds of queries (e.g. MongoDB).
- * In those cases, you may set this property to be false to skip the validation (you may need to validate yourself then).
- * Defaults to true.
- * @since 1.1.4
+ * @var string the route (controller ID and action ID) for displaying the paged contents.
+ * If not set, it means using the currently requested route.
*/
- public $validateCurrentPage = true;
-
- private $_pageSize = self::DEFAULT_PAGE_SIZE;
- private $_itemCount = 0;
- private $_currentPage;
-
+ public $route;
/**
- * Constructor.
- * @param integer $itemCount total number of items.
+ * @var array parameters (name=>value) that should be used to obtain the current page number
+ * and to create new pagination URLs. If not set, $_GET will be used instead.
+ * The array element indexed by [[pageVar]] is considered to be the current page number.
+ * If the element does not exist, the current page number is considered 0.
*/
- public function __construct($itemCount = 0)
- {
- $this->setItemCount($itemCount);
- }
-
+ public $params;
/**
- * @return integer number of items in each page. Defaults to 10.
+ * @var boolean whether to check if [[page]] is within valid range.
+ * When this property is true, the value of [[page]] will always be between 0 and ([[pageCount]]-1).
+ * Because [[pageCount]] relies on the correct value of [[itemCount]] which may not be available
+ * in some cases (e.g. MongoDB), you may want to set this property to be false to disable the page
+ * number validation. By doing so, [[page]] will return the value indexed by [[pageVar]] in [[params]].
*/
- public function getPageSize()
- {
- return $this->_pageSize;
- }
-
+ public $validatePage = true;
/**
- * @param integer $value number of items in each page
+ * @var integer number of items on each page. Defaults to 10.
+ * If it is less than 1, it means the page size is infinite, and thus a single page contains all items.
*/
- public function setPageSize($value)
- {
- if (($this->_pageSize = $value) <= 0) {
- $this->_pageSize = self::DEFAULT_PAGE_SIZE;
- }
- }
-
+ public $pageSize = 10;
/**
- * @return integer total number of items. Defaults to 0.
+ * @var integer total number of items.
*/
- public function getItemCount()
- {
- return $this->_itemCount;
- }
+ public $itemCount;
/**
- * @param integer $value total number of items.
+ * Constructor.
+ * @param integer $itemCount total number of items.
+ * @param array $config name-value pairs that will be used to initialize the object properties
*/
- public function setItemCount($value)
+ public function __construct($itemCount, $config = array())
{
- if (($this->_itemCount = $value) < 0) {
- $this->_itemCount = 0;
- }
+ $this->itemCount = $itemCount;
+ parent::__construct($config);
}
/**
@@ -150,94 +119,88 @@ class Pagination extends \yii\base\Object
*/
public function getPageCount()
{
- return (int)(($this->_itemCount + $this->_pageSize - 1) / $this->_pageSize);
+ if ($this->pageSize < 1) {
+ return $this->itemCount > 0 ? 1 : 0;
+ } else {
+ $itemCount = $this->itemCount < 0 ? 0 : (int)$this->itemCount;
+ return (int)(($itemCount + $this->pageSize - 1) / $this->pageSize);
+ }
}
+ private $_page;
+
/**
+ * Returns the zero-based current page number.
* @param boolean $recalculate whether to recalculate the current page based on the page size and item count.
- * @return integer the zero-based index of the current page. Defaults to 0.
+ * @return integer the zero-based current page number.
*/
- public function getCurrentPage($recalculate = true)
+ public function getPage($recalculate = false)
{
- if ($this->_currentPage === null || $recalculate) {
- if (isset($_GET[$this->pageVar])) {
- $this->_currentPage = (int)$_GET[$this->pageVar] - 1;
- if ($this->validateCurrentPage) {
+ if ($this->_page === null || $recalculate) {
+ $params = $this->params === null ? $_GET : $this->params;
+ if (isset($params[$this->pageVar])) {
+ $this->_page = (int)$params[$this->pageVar] - 1;
+ if ($this->validatePage) {
$pageCount = $this->getPageCount();
- if ($this->_currentPage >= $pageCount) {
- $this->_currentPage = $pageCount - 1;
+ if ($this->_page >= $pageCount) {
+ $this->_page = $pageCount - 1;
}
}
- if ($this->_currentPage < 0) {
- $this->_currentPage = 0;
+ if ($this->_page < 0) {
+ $this->_page = 0;
}
} else {
- $this->_currentPage = 0;
+ $this->_page = 0;
}
}
- return $this->_currentPage;
+ return $this->_page;
}
/**
+ * Sets the current page number.
* @param integer $value the zero-based index of the current page.
*/
- public function setCurrentPage($value)
+ public function setPage($value)
{
- $this->_currentPage = $value;
- $_GET[$this->pageVar] = $value + 1;
+ $this->_page = $value;
}
/**
- * Creates the URL suitable for pagination.
- * This method is mainly called by pagers when creating URLs used to
- * perform pagination. The default implementation is to call
- * the controller's createUrl method with the page information.
- * You may override this method if your URL scheme is not the same as
- * the one supported by the controller's createUrl method.
- * @param CController $controller the controller that will create the actual URL
- * @param integer $page the page that the URL should point to. This is a zero-based index.
+ * Creates the URL suitable for pagination with the specified page number.
+ * This method is mainly called by pagers when creating URLs used to perform pagination.
+ * @param integer $page the zero-based page number that the URL should point to.
* @return string the created URL
+ * @see params
+ * @see forcePageVar
*/
- public function createPageUrl($controller, $page)
+ public function createUrl($page)
{
$params = $this->params === null ? $_GET : $this->params;
- if ($page > 0) // page 0 is the default
- {
+ if ($page > 0 || $page >= 0 && $this->forcePageVar) {
$params[$this->pageVar] = $page + 1;
} else {
unset($params[$this->pageVar]);
}
- return $controller->createUrl($this->route, $params);
- }
-
- /**
- * Applies LIMIT and OFFSET to the specified query criteria.
- * @param CDbCriteria $criteria the query criteria that should be applied with the limit
- */
- public function applyLimit($criteria)
- {
- $criteria->limit = $this->getLimit();
- $criteria->offset = $this->getOffset();
+ $route = $this->route === null ? Yii::$app->controller->route : $this->route;
+ return Yii::$app->getUrlManager()->createUrl($route, $params);
}
/**
* @return integer the offset of the data. This may be used to set the
* OFFSET value for a SQL statement for fetching the current page of data.
- * @since 1.1.0
*/
public function getOffset()
{
- return $this->getCurrentPage() * $this->getPageSize();
+ return $this->pageSize < 1 ? 0 : $this->getPage() * $this->pageSize;
}
/**
* @return integer the limit of the data. This may be used to set the
* LIMIT value for a SQL statement for fetching the current page of data.
- * This returns the same value as {@link pageSize}.
- * @since 1.1.0
+ * Note that if the page size is infinite, a value -1 will be returned.
*/
public function getLimit()
{
- return $this->getPageSize();
+ return $this->pageSize < 1 ? -1 : $this->pageSize;
}
}
\ No newline at end of file