From 51c1e313086f34c5f8a88466833f9e58aaaf6909 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Wed, 5 Jun 2013 17:36:21 -0400 Subject: [PATCH] moved Pagination and Sort to data. --- framework/yii/data/Pagination.php | 209 ++++++++++++++++++++++ framework/yii/data/Sort.php | 337 ++++++++++++++++++++++++++++++++++++ framework/yii/web/Pagination.php | 208 ---------------------- framework/yii/web/Sort.php | 336 ----------------------------------- framework/yii/widgets/LinkPager.php | 4 +- framework/yii/widgets/ListPager.php | 4 +- 6 files changed, 550 insertions(+), 548 deletions(-) create mode 100644 framework/yii/data/Pagination.php create mode 100644 framework/yii/data/Sort.php delete mode 100644 framework/yii/web/Pagination.php delete mode 100644 framework/yii/web/Sort.php diff --git a/framework/yii/data/Pagination.php b/framework/yii/data/Pagination.php new file mode 100644 index 0000000..4e25809 --- /dev/null +++ b/framework/yii/data/Pagination.php @@ -0,0 +1,209 @@ +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, + * 'pages' => $pages, + * )); + * } + * ~~~ + * + * View: + * + * ~~~ + * foreach ($models as $model) { + * // display $model here + * } + * + * // display pagination + * LinkPager::widget(array( + * 'pagination' => $pages, + * )); + * ~~~ + * + * @property integer $pageCount Number of pages. + * @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. + * + * @author Qiang Xue + * @since 2.0 + */ +class Pagination extends Object +{ + /** + * @var string name of the parameter storing the current page index. Defaults to 'page'. + * @see params + */ + public $pageVar = 'page'; + /** + * @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 $forcePageVar = true; + /** + * @var string the route of the controller action for displaying the paged contents. + * If not set, it means using the currently requested route. + */ + public $route; + /** + * @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 $params; + /** + * @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 $validatePage = true; + /** + * @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 $pageSize = 10; + /** + * @var integer total number of items. + */ + public $itemCount; + + /** + * 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 __construct($itemCount, $config = array()) + { + $this->itemCount = $itemCount; + parent::__construct($config); + } + + /** + * @return integer number of pages + */ + public function getPageCount() + { + 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 current page number. + */ + public function getPage($recalculate = false) + { + if ($this->_page === null || $recalculate) { + $params = $this->params === null ? $_GET : $this->params; + if (isset($params[$this->pageVar]) && is_scalar($params[$this->pageVar])) { + $this->_page = (int)$params[$this->pageVar] - 1; + if ($this->validatePage) { + $pageCount = $this->getPageCount(); + if ($this->_page >= $pageCount) { + $this->_page = $pageCount - 1; + } + } + if ($this->_page < 0) { + $this->_page = 0; + } + } else { + $this->_page = 0; + } + } + return $this->_page; + } + + /** + * Sets the current page number. + * @param integer $value the zero-based index of the current page. + */ + public function setPage($value) + { + $this->_page = $value; + } + + /** + * 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 createUrl($page) + { + $params = $this->params === null ? $_GET : $this->params; + if ($page > 0 || $page >= 0 && $this->forcePageVar) { + $params[$this->pageVar] = $page + 1; + } else { + unset($params[$this->pageVar]); + } + $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. + */ + public function getOffset() + { + 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. + * Note that if the page size is infinite, a value -1 will be returned. + */ + public function getLimit() + { + return $this->pageSize < 1 ? -1 : $this->pageSize; + } +} diff --git a/framework/yii/data/Sort.php b/framework/yii/data/Sort.php new file mode 100644 index 0000000..a46d0ce --- /dev/null +++ b/framework/yii/data/Sort.php @@ -0,0 +1,337 @@ + array( + * 'age', + * 'name' => array( + * 'asc' => array('last_name', 'first_name'), + * 'desc' => array('last_name' => true, 'first_name' => true), + * ), + * ), + * )); + * + * $models = Article::find() + * ->where(array('status' => 1)) + * ->orderBy($sort->orders) + * ->all(); + * + * $this->render('index', array( + * 'models' => $models, + * 'sort' => $sort, + * )); + * } + * ~~~ + * + * View: + * + * ~~~ + * // display links leading to sort actions + * echo $sort->link('name', 'Name') . ' | ' . $sort->link('age', 'Age'); + * + * foreach ($models as $model) { + * // display $model here + * } + * ~~~ + * + * In the above, we declare two [[attributes]] that support sorting: name and age. + * We pass the sort information to the Article query so that the query results are + * sorted by the orders specified by the Sort object. In the view, we show two hyperlinks + * that can lead to pages with the data sorted by the corresponding attributes. + * + * @property array $orders Sort directions indexed by column names. The sort direction + * can be either [[Sort::ASC]] for ascending order or [[Sort::DESC]] for descending order. + * @property array $attributeOrders Sort directions indexed by attribute names. The sort + * direction can be either [[Sort::ASC]] for ascending order or [[Sort::DESC]] for descending order. + * + * @author Qiang Xue + * @since 2.0 + */ +class Sort extends Object +{ + /** + * Sort ascending + */ + const ASC = false; + + /** + * Sort descending + */ + const DESC = true; + + /** + * @var boolean whether the sorting can be applied to multiple attributes simultaneously. + * Defaults to false, which means each time the data can only be sorted by one attribute. + */ + public $enableMultiSort = false; + + /** + * @var array list of attributes that are allowed to be sorted. Its syntax can be + * described using the following example: + * + * ~~~ + * array( + * 'age', + * 'user' => array( + * 'asc' => array('first_name' => Sort::ASC, 'last_name' => Sort::ASC), + * 'desc' => array('first_name' => Sort::DESC, 'last_name' => Sort::DESC), + * 'default' => 'desc', + * ), + * ) + * ~~~ + * + * In the above, two attributes are declared: "age" and "user". The "age" attribute is + * a simple attribute which is equivalent to the following: + * + * ~~~ + * 'age' => array( + * 'asc' => array('age' => Sort::ASC), + * 'desc' => array('age' => Sort::DESC), + * ) + * ~~~ + * + * The "user" attribute is a composite attribute: + * + * - The "user" key represents the attribute name which will appear in the URLs leading + * to sort actions. Attribute names cannot contain characters listed in [[separators]]. + * - The "asc" and "desc" elements specify how to sort by the attribute in ascending + * and descending orders, respectively. Their values represent the actual columns and + * the directions by which the data should be sorted by. + * - And the "default" element specifies if the attribute is not sorted currently, + * in which direction it should be sorted (the default value is ascending order). + */ + public $attributes = array(); + /** + * @var string the name of the parameter that specifies which attributes to be sorted + * in which direction. Defaults to 'sort'. + * @see params + */ + public $sortVar = 'sort'; + /** + * @var string the tag appeared in the [[sortVar]] parameter that indicates the attribute should be sorted + * in descending order. Defaults to 'desc'. + */ + public $descTag = 'desc'; + /** + * @var array the order that should be used when the current request does not specify any order. + * The array keys are attribute names and the array values are the corresponding sort directions. For example, + * + * ~~~ + * array( + * 'name' => Sort::ASC, + * 'create_time' => Sort::DESC, + * ) + * ~~~ + * + * @see attributeOrders + */ + public $defaults; + /** + * @var string the route of the controller action for displaying the sorted contents. + * If not set, it means using the currently requested route. + */ + public $route; + /** + * @var array separators used in the generated URL. This must be an array consisting of + * two elements. The first element specifies the character separating different + * attributes, while the second element specifies the character separating attribute name + * and the corresponding sort direction. Defaults to `array('-', '.')`. + */ + public $separators = array('-', '.'); + /** + * @var array parameters (name => value) that should be used to obtain the current sort directions + * and to create new sort URLs. If not set, $_GET will be used instead. + * + * The array element indexed by [[sortVar]] is considered to be the current sort directions. + * If the element does not exist, the [[defaults|default order]] will be used. + * + * @see sortVar + * @see defaults + */ + public $params; + + /** + * Returns the columns and their corresponding sort directions. + * @return array the columns (keys) and their corresponding sort directions (values). + * This can be passed to [[\yii\db\Query::orderBy()]] to construct a DB query. + */ + public function getOrders() + { + $attributeOrders = $this->getAttributeOrders(); + $orders = array(); + foreach ($attributeOrders as $attribute => $direction) { + $definition = $this->getAttribute($attribute); + $columns = $definition[$direction === self::ASC ? 'asc' : 'desc']; + foreach ($columns as $name => $dir) { + $orders[$name] = $dir; + } + } + return $orders; + } + + /** + * Generates a hyperlink that links to the sort action to sort by the specified attribute. + * Based on the sort direction, the CSS class of the generated hyperlink will be appended + * with "asc" or "desc". + * @param string $attribute the attribute name by which the data should be sorted by. + * @param string $label the link label. Note that the label will not be HTML-encoded. + * @param array $htmlOptions additional HTML attributes for the hyperlink tag + * @return string the generated hyperlink + */ + public function link($attribute, $label, $htmlOptions = array()) + { + if (($definition = $this->getAttribute($attribute)) === false) { + return $label; + } + + if (($direction = $this->getAttributeOrder($attribute)) !== null) { + $class = $direction ? 'desc' : 'asc'; + if (isset($htmlOptions['class'])) { + $htmlOptions['class'] .= ' ' . $class; + } else { + $htmlOptions['class'] = $class; + } + } + + $url = $this->createUrl($attribute); + + return Html::a($label, $url, $htmlOptions); + } + + private $_attributeOrders; + + /** + * Returns the currently requested sort information. + * @param boolean $recalculate whether to recalculate the sort directions + * @return array sort directions indexed by attribute names. + * Sort direction can be either [[Sort::ASC]] for ascending order or + * [[Sort::DESC]] for descending order. + */ + public function getAttributeOrders($recalculate = false) + { + if ($this->_attributeOrders === null || $recalculate) { + $this->_attributeOrders = array(); + $params = $this->params === null ? $_GET : $this->params; + if (isset($params[$this->sortVar]) && is_scalar($params[$this->sortVar])) { + $attributes = explode($this->separators[0], $params[$this->sortVar]); + foreach ($attributes as $attribute) { + $descending = false; + if (($pos = strrpos($attribute, $this->separators[1])) !== false) { + if ($descending = (substr($attribute, $pos + 1) === $this->descTag)) { + $attribute = substr($attribute, 0, $pos); + } + } + + if (($this->getAttribute($attribute)) !== false) { + $this->_attributeOrders[$attribute] = $descending; + if (!$this->enableMultiSort) { + return $this->_attributeOrders; + } + } + } + } + if (empty($this->_attributeOrders) && is_array($this->defaults)) { + $this->_attributeOrders = $this->defaults; + } + } + return $this->_attributeOrders; + } + + /** + * Returns the sort direction of the specified attribute in the current request. + * @param string $attribute the attribute name + * @return boolean|null Sort direction of the attribute. Can be either [[Sort::ASC]] + * for ascending order or [[Sort::DESC]] for descending order. Null is returned + * if the attribute is invalid or does not need to be sorted. + */ + public function getAttributeOrder($attribute) + { + $this->getAttributeOrders(); + return isset($this->_attributeOrders[$attribute]) ? $this->_attributeOrders[$attribute] : null; + } + + /** + * Creates a URL for sorting the data by the specified attribute. + * This method will consider the current sorting status given by [[attributeOrders]]. + * For example, if the current page already sorts the data by the specified attribute in ascending order, + * then the URL created will lead to a page that sorts the data by the specified attribute in descending order. + * @param string $attribute the attribute name + * @return string|boolean the URL for sorting. False if the attribute is invalid. + * @see attributeOrders + * @see params + */ + public function createUrl($attribute) + { + if (($definition = $this->getAttribute($attribute)) === false) { + return false; + } + $directions = $this->getAttributeOrders(); + if (isset($directions[$attribute])) { + $descending = !$directions[$attribute]; + unset($directions[$attribute]); + } elseif (isset($definition['default'])) { + $descending = $definition['default'] === 'desc'; + } else { + $descending = false; + } + + if ($this->enableMultiSort) { + $directions = array_merge(array($attribute => $descending), $directions); + } else { + $directions = array($attribute => $descending); + } + + $sorts = array(); + foreach ($directions as $attribute => $descending) { + $sorts[] = $descending ? $attribute . $this->separators[1] . $this->descTag : $attribute; + } + $params = $this->params === null ? $_GET : $this->params; + $params[$this->sortVar] = implode($this->separators[0], $sorts); + $route = $this->route === null ? Yii::$app->controller->route : $this->route; + + return Yii::$app->getUrlManager()->createUrl($route, $params); + } + + /** + * Returns the attribute definition of the specified name. + * @param string $name the attribute name + * @return array|boolean the sort definition (column names => sort directions). + * False is returned if the attribute cannot be sorted. + * @see attributes + */ + public function getAttribute($name) + { + if (isset($this->attributes[$name])) { + return $this->attributes[$name]; + } elseif (in_array($name, $this->attributes, true)) { + return array( + 'asc' => array($name => self::ASC), + 'desc' => array($name => self::DESC), + ); + } else { + return false; + } + } +} diff --git a/framework/yii/web/Pagination.php b/framework/yii/web/Pagination.php deleted file mode 100644 index c4a8106..0000000 --- a/framework/yii/web/Pagination.php +++ /dev/null @@ -1,208 +0,0 @@ -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, - * 'pages' => $pages, - * )); - * } - * ~~~ - * - * View: - * - * ~~~ - * foreach ($models as $model) { - * // display $model here - * } - * - * // display pagination - * LinkPager::widget(array( - * 'pagination' => $pages, - * )); - * ~~~ - * - * @property integer $pageCount Number of pages. - * @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. - * - * @author Qiang Xue - * @since 2.0 - */ -class Pagination extends \yii\base\Object -{ - /** - * @var string name of the parameter storing the current page index. Defaults to 'page'. - * @see params - */ - public $pageVar = 'page'; - /** - * @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 $forcePageVar = true; - /** - * @var string the route of the controller action for displaying the paged contents. - * If not set, it means using the currently requested route. - */ - public $route; - /** - * @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 $params; - /** - * @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 $validatePage = true; - /** - * @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 $pageSize = 10; - /** - * @var integer total number of items. - */ - public $itemCount; - - /** - * 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 __construct($itemCount, $config = array()) - { - $this->itemCount = $itemCount; - parent::__construct($config); - } - - /** - * @return integer number of pages - */ - public function getPageCount() - { - 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 current page number. - */ - public function getPage($recalculate = false) - { - if ($this->_page === null || $recalculate) { - $params = $this->params === null ? $_GET : $this->params; - if (isset($params[$this->pageVar]) && is_scalar($params[$this->pageVar])) { - $this->_page = (int)$params[$this->pageVar] - 1; - if ($this->validatePage) { - $pageCount = $this->getPageCount(); - if ($this->_page >= $pageCount) { - $this->_page = $pageCount - 1; - } - } - if ($this->_page < 0) { - $this->_page = 0; - } - } else { - $this->_page = 0; - } - } - return $this->_page; - } - - /** - * Sets the current page number. - * @param integer $value the zero-based index of the current page. - */ - public function setPage($value) - { - $this->_page = $value; - } - - /** - * 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 createUrl($page) - { - $params = $this->params === null ? $_GET : $this->params; - if ($page > 0 || $page >= 0 && $this->forcePageVar) { - $params[$this->pageVar] = $page + 1; - } else { - unset($params[$this->pageVar]); - } - $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. - */ - public function getOffset() - { - 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. - * Note that if the page size is infinite, a value -1 will be returned. - */ - public function getLimit() - { - return $this->pageSize < 1 ? -1 : $this->pageSize; - } -} diff --git a/framework/yii/web/Sort.php b/framework/yii/web/Sort.php deleted file mode 100644 index 6014a3e..0000000 --- a/framework/yii/web/Sort.php +++ /dev/null @@ -1,336 +0,0 @@ - array( - * 'age', - * 'name' => array( - * 'asc' => array('last_name', 'first_name'), - * 'desc' => array('last_name' => true, 'first_name' => true), - * ), - * ), - * )); - * - * $models = Article::find() - * ->where(array('status' => 1)) - * ->orderBy($sort->orders) - * ->all(); - * - * $this->render('index', array( - * 'models' => $models, - * 'sort' => $sort, - * )); - * } - * ~~~ - * - * View: - * - * ~~~ - * // display links leading to sort actions - * echo $sort->link('name', 'Name') . ' | ' . $sort->link('age', 'Age'); - * - * foreach ($models as $model) { - * // display $model here - * } - * ~~~ - * - * In the above, we declare two [[attributes]] that support sorting: name and age. - * We pass the sort information to the Article query so that the query results are - * sorted by the orders specified by the Sort object. In the view, we show two hyperlinks - * that can lead to pages with the data sorted by the corresponding attributes. - * - * @property array $orders Sort directions indexed by column names. The sort direction - * can be either [[Sort::ASC]] for ascending order or [[Sort::DESC]] for descending order. - * @property array $attributeOrders Sort directions indexed by attribute names. The sort - * direction can be either [[Sort::ASC]] for ascending order or [[Sort::DESC]] for descending order. - * - * @author Qiang Xue - * @since 2.0 - */ -class Sort extends \yii\base\Object -{ - /** - * Sort ascending - */ - const ASC = false; - - /** - * Sort descending - */ - const DESC = true; - - /** - * @var boolean whether the sorting can be applied to multiple attributes simultaneously. - * Defaults to false, which means each time the data can only be sorted by one attribute. - */ - public $enableMultiSort = false; - - /** - * @var array list of attributes that are allowed to be sorted. Its syntax can be - * described using the following example: - * - * ~~~ - * array( - * 'age', - * 'user' => array( - * 'asc' => array('first_name' => Sort::ASC, 'last_name' => Sort::ASC), - * 'desc' => array('first_name' => Sort::DESC, 'last_name' => Sort::DESC), - * 'default' => 'desc', - * ), - * ) - * ~~~ - * - * In the above, two attributes are declared: "age" and "user". The "age" attribute is - * a simple attribute which is equivalent to the following: - * - * ~~~ - * 'age' => array( - * 'asc' => array('age' => Sort::ASC), - * 'desc' => array('age' => Sort::DESC), - * ) - * ~~~ - * - * The "user" attribute is a composite attribute: - * - * - The "user" key represents the attribute name which will appear in the URLs leading - * to sort actions. Attribute names cannot contain characters listed in [[separators]]. - * - The "asc" and "desc" elements specify how to sort by the attribute in ascending - * and descending orders, respectively. Their values represent the actual columns and - * the directions by which the data should be sorted by. - * - And the "default" element specifies if the attribute is not sorted currently, - * in which direction it should be sorted (the default value is ascending order). - */ - public $attributes = array(); - /** - * @var string the name of the parameter that specifies which attributes to be sorted - * in which direction. Defaults to 'sort'. - * @see params - */ - public $sortVar = 'sort'; - /** - * @var string the tag appeared in the [[sortVar]] parameter that indicates the attribute should be sorted - * in descending order. Defaults to 'desc'. - */ - public $descTag = 'desc'; - /** - * @var array the order that should be used when the current request does not specify any order. - * The array keys are attribute names and the array values are the corresponding sort directions. For example, - * - * ~~~ - * array( - * 'name' => Sort::ASC, - * 'create_time' => Sort::DESC, - * ) - * ~~~ - * - * @see attributeOrders - */ - public $defaults; - /** - * @var string the route of the controller action for displaying the sorted contents. - * If not set, it means using the currently requested route. - */ - public $route; - /** - * @var array separators used in the generated URL. This must be an array consisting of - * two elements. The first element specifies the character separating different - * attributes, while the second element specifies the character separating attribute name - * and the corresponding sort direction. Defaults to `array('-', '.')`. - */ - public $separators = array('-', '.'); - /** - * @var array parameters (name => value) that should be used to obtain the current sort directions - * and to create new sort URLs. If not set, $_GET will be used instead. - * - * The array element indexed by [[sortVar]] is considered to be the current sort directions. - * If the element does not exist, the [[defaults|default order]] will be used. - * - * @see sortVar - * @see defaults - */ - public $params; - - /** - * Returns the columns and their corresponding sort directions. - * @return array the columns (keys) and their corresponding sort directions (values). - * This can be passed to [[\yii\db\Query::orderBy()]] to construct a DB query. - */ - public function getOrders() - { - $attributeOrders = $this->getAttributeOrders(); - $orders = array(); - foreach ($attributeOrders as $attribute => $direction) { - $definition = $this->getAttribute($attribute); - $columns = $definition[$direction === self::ASC ? 'asc' : 'desc']; - foreach ($columns as $name => $dir) { - $orders[$name] = $dir; - } - } - return $orders; - } - - /** - * Generates a hyperlink that links to the sort action to sort by the specified attribute. - * Based on the sort direction, the CSS class of the generated hyperlink will be appended - * with "asc" or "desc". - * @param string $attribute the attribute name by which the data should be sorted by. - * @param string $label the link label. Note that the label will not be HTML-encoded. - * @param array $htmlOptions additional HTML attributes for the hyperlink tag - * @return string the generated hyperlink - */ - public function link($attribute, $label, $htmlOptions = array()) - { - if (($definition = $this->getAttribute($attribute)) === false) { - return $label; - } - - if (($direction = $this->getAttributeOrder($attribute)) !== null) { - $class = $direction ? 'desc' : 'asc'; - if (isset($htmlOptions['class'])) { - $htmlOptions['class'] .= ' ' . $class; - } else { - $htmlOptions['class'] = $class; - } - } - - $url = $this->createUrl($attribute); - - return Html::a($label, $url, $htmlOptions); - } - - private $_attributeOrders; - - /** - * Returns the currently requested sort information. - * @param boolean $recalculate whether to recalculate the sort directions - * @return array sort directions indexed by attribute names. - * Sort direction can be either [[Sort::ASC]] for ascending order or - * [[Sort::DESC]] for descending order. - */ - public function getAttributeOrders($recalculate = false) - { - if ($this->_attributeOrders === null || $recalculate) { - $this->_attributeOrders = array(); - $params = $this->params === null ? $_GET : $this->params; - if (isset($params[$this->sortVar]) && is_scalar($params[$this->sortVar])) { - $attributes = explode($this->separators[0], $params[$this->sortVar]); - foreach ($attributes as $attribute) { - $descending = false; - if (($pos = strrpos($attribute, $this->separators[1])) !== false) { - if ($descending = (substr($attribute, $pos + 1) === $this->descTag)) { - $attribute = substr($attribute, 0, $pos); - } - } - - if (($this->getAttribute($attribute)) !== false) { - $this->_attributeOrders[$attribute] = $descending; - if (!$this->enableMultiSort) { - return $this->_attributeOrders; - } - } - } - } - if (empty($this->_attributeOrders) && is_array($this->defaults)) { - $this->_attributeOrders = $this->defaults; - } - } - return $this->_attributeOrders; - } - - /** - * Returns the sort direction of the specified attribute in the current request. - * @param string $attribute the attribute name - * @return boolean|null Sort direction of the attribute. Can be either [[Sort::ASC]] - * for ascending order or [[Sort::DESC]] for descending order. Null is returned - * if the attribute is invalid or does not need to be sorted. - */ - public function getAttributeOrder($attribute) - { - $this->getAttributeOrders(); - return isset($this->_attributeOrders[$attribute]) ? $this->_attributeOrders[$attribute] : null; - } - - /** - * Creates a URL for sorting the data by the specified attribute. - * This method will consider the current sorting status given by [[attributeOrders]]. - * For example, if the current page already sorts the data by the specified attribute in ascending order, - * then the URL created will lead to a page that sorts the data by the specified attribute in descending order. - * @param string $attribute the attribute name - * @return string|boolean the URL for sorting. False if the attribute is invalid. - * @see attributeOrders - * @see params - */ - public function createUrl($attribute) - { - if (($definition = $this->getAttribute($attribute)) === false) { - return false; - } - $directions = $this->getAttributeOrders(); - if (isset($directions[$attribute])) { - $descending = !$directions[$attribute]; - unset($directions[$attribute]); - } elseif (isset($definition['default'])) { - $descending = $definition['default'] === 'desc'; - } else { - $descending = false; - } - - if ($this->enableMultiSort) { - $directions = array_merge(array($attribute => $descending), $directions); - } else { - $directions = array($attribute => $descending); - } - - $sorts = array(); - foreach ($directions as $attribute => $descending) { - $sorts[] = $descending ? $attribute . $this->separators[1] . $this->descTag : $attribute; - } - $params = $this->params === null ? $_GET : $this->params; - $params[$this->sortVar] = implode($this->separators[0], $sorts); - $route = $this->route === null ? Yii::$app->controller->route : $this->route; - - return Yii::$app->getUrlManager()->createUrl($route, $params); - } - - /** - * Returns the attribute definition of the specified name. - * @param string $name the attribute name - * @return array|boolean the sort definition (column names => sort directions). - * False is returned if the attribute cannot be sorted. - * @see attributes - */ - public function getAttribute($name) - { - if (isset($this->attributes[$name])) { - return $this->attributes[$name]; - } elseif (in_array($name, $this->attributes, true)) { - return array( - 'asc' => array($name => self::ASC), - 'desc' => array($name => self::DESC), - ); - } else { - return false; - } - } -} diff --git a/framework/yii/widgets/LinkPager.php b/framework/yii/widgets/LinkPager.php index 2510579..62d99f6 100644 --- a/framework/yii/widgets/LinkPager.php +++ b/framework/yii/widgets/LinkPager.php @@ -11,7 +11,7 @@ use Yii; use yii\base\InvalidConfigException; use yii\helpers\Html; use yii\base\Widget; -use yii\web\Pagination; +use yii\data\Pagination; /** * LinkPager displays a list of hyperlinks that lead to different pages of target. @@ -198,4 +198,4 @@ class LinkPager extends Widget } return array($beginPage, $endPage); } -} \ No newline at end of file +} diff --git a/framework/yii/widgets/ListPager.php b/framework/yii/widgets/ListPager.php index 7b16f7d..699126d 100644 --- a/framework/yii/widgets/ListPager.php +++ b/framework/yii/widgets/ListPager.php @@ -10,7 +10,7 @@ namespace yii\widgets; use yii\base\InvalidConfigException; use yii\helpers\Html; use yii\base\Widget; -use yii\web\Pagination; +use yii\data\Pagination; /** * ListPager displays a drop-down list that contains options leading to different pages. @@ -92,4 +92,4 @@ class ListPager extends Widget )); } -} \ No newline at end of file +}