|
Server IP : 10.2.73.233 / Your IP : 216.73.216.59 Web Server : Apache/2.4.59 (Debian) System : Linux polon 4.19.0-27-amd64 #1 SMP Debian 4.19.316-1 (2024-06-25) x86_64 User : www-data ( 33) PHP Version : 5.6.40-64+0~20230107.71+debian10~1.gbp673146 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority, MySQL : ON | cURL : ON | WGET : ON | Perl : ON | Python : ON Directory (0755) : /home/ifk/web/prado4.3.2/Collections/ |
| [ Home ] | [ C0mmand ] | [ Upload File ] |
|---|
<?php
/**
* TPagedList, TPagedListFetchDataEventParameter, TPagedListPageChangedEventParameter class file
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link https://github.com/pradosoft/prado
* @license https://github.com/pradosoft/prado/blob/master/LICENSE
*/
namespace Prado\Collections;
use Prado\Exceptions\TInvalidDataValueException;
use Prado\TPropertyValue;
/**
* TPagedList class
*
* TPagedList implements a list with paging functionality.
*
* TPagedList works in one of two modes, managed paging or customized paging,
* specified by {@link setCustomPaging CustomPaging}.
* - Managed paging ({@link setCustomPaging CustomPaging}=false) :
* the list is assumed to contain all data and it will manage which page
* of data are available to user.
* - Customized paging ({@link setCustomPaging CustomPaging}=true) :
* the list is assumed to contain only one page of data. An {@link onFetchData OnFetchData}
* event will be raised if the list changes to a different page.
* Developers can attach a handler to the event and supply the needed data.
* The event handler can be written as follows,
* <code>
* public function fetchData($sender,$param)
* {
* $offset=$param->Offset; // beginning index of the data needed
* $limit=$param->Limit; // maximum number of data items needed
* // get data according to the above two parameters
* $param->Data=$data;
* }
* </code>
*
* Data in TPagedList can be accessed like an integer-indexed array and can
* be traversed using foreach. For example,
* <code>
* $count=$list->Count;
* for($index=0;$index<$count;++$index)
* echo $list[$index];
* foreach($list as $index=>$item) // traverse each item in the list
* </code>
*
* The {@link setPageSize PageSize} property specifies the number of items in each page.
* To access different page of data in the list, set {@link setCurrentPageIndex CurrentPageIndex}
* or call {@link nextPage()}, {@link previousPage()}, or {@link gotoPage()}.
* The total number of pages can be obtained by {@link getPageCount() PageCount}.
*
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 3.0
*/
class TPagedList extends TList
{
/**
* @var bool whether to allow custom paging
*/
private $_customPaging = false;
/**
* @var int number of items in each page
*/
private $_pageSize = 10;
/**
* @var int current page index
*/
private $_currentPageIndex = -1;
/**
* @var int user-assigned number of items in data source
*/
private $_virtualCount = -1;
/**
* Constructor.
* @param null|array|\Iterator $data the initial data. Default is null, meaning no initialization.
* @param bool $readOnly whether the list is read-only. Always true for paged list.
*/
public function __construct($data = null, $readOnly = false)
{
$readOnly = true;
parent::__construct($data, $readOnly);
}
/**
* @return bool whether to use custom paging. Defaults to false.
*/
public function getCustomPaging()
{
return $this->_customPaging;
}
/**
* @param bool $value whether to allow custom paging
*/
public function setCustomPaging($value)
{
$this->_customPaging = TPropertyValue::ensureBoolean($value);
}
/**
* @return int number of items in each page. Defaults to 10.
*/
public function getPageSize()
{
return $this->_pageSize;
}
/**
* @param int $value number of items in each page
*/
public function setPageSize($value)
{
if (($value = TPropertyValue::ensureInteger($value)) > 0) {
$this->_pageSize = $value;
} else {
throw new TInvalidDataValueException('pagedlist_pagesize_invalid');
}
}
/**
* @return int current page index. Defaults to 0.
*/
public function getCurrentPageIndex()
{
return $this->_currentPageIndex;
}
/**
* @param int $value current page index
* @throws TInvalidDataValueException if the page index is out of range
*/
public function setCurrentPageIndex($value)
{
if ($this->gotoPage($value = TPropertyValue::ensureInteger($value)) === false) {
throw new TInvalidDataValueException('pagedlist_currentpageindex_invalid');
}
}
/**
* Raises <b>OnPageIndexChanged</b> event.
* This event is raised each time when the list changes to a different page.
* @param TPagedListPageChangedEventParameter $param event parameter
*/
public function onPageIndexChanged($param)
{
$this->raiseEvent('OnPageIndexChanged', $this, $param);
}
/**
* Raises <b>OnFetchData</b> event.
* This event is raised each time when the list changes to a different page
* and needs the new page of data. This event can only be raised when
* {@link setCustomPaging CustomPaging} is true.
* @param TPagedListFetchDataEventParameter $param event parameter
*/
public function onFetchData($param)
{
$this->raiseEvent('OnFetchData', $this, $param);
}
/**
* Changes to a page with the specified page index.
* @param int $pageIndex page index
* @return bool|int the new page index, false if page index is out of range.
*/
public function gotoPage($pageIndex)
{
if ($pageIndex === $this->_currentPageIndex) {
return $pageIndex;
}
if ($this->_customPaging) {
if ($pageIndex >= 0 && ($this->_virtualCount < 0 || $pageIndex < $this->getPageCount())) {
$param = new TPagedListFetchDataEventParameter($pageIndex, $this->_pageSize * $pageIndex, $this->_pageSize);
$this->onFetchData($param);
if (($data = $param->getData()) !== null) {
$this->setReadOnly(false);
$this->copyFrom($data);
$this->setReadOnly(true);
$oldPage = $this->_currentPageIndex;
$this->_currentPageIndex = $pageIndex;
$this->onPageIndexChanged(new TPagedListPageChangedEventParameter($oldPage));
return $pageIndex;
} else {
return false;
}
} else {
return false;
}
} else {
if ($pageIndex >= 0 && $pageIndex < $this->getPageCount()) {
$this->_currentPageIndex = $pageIndex;
$this->onPageIndexChanged(null);
return $pageIndex;
} else {
return false;
}
}
}
/**
* Switches to the next page.
* @return bool|int the new page index, false if next page is not available.
*/
public function nextPage()
{
return $this->gotoPage($this->_currentPageIndex + 1);
}
/**
* Switches to the previous page.
* @return bool|int the new page index, false if previous page is not available.
*/
public function previousPage()
{
return $this->gotoPage($this->_currentPageIndex - 1);
}
/**
* @return int user-assigned number of items in data source. Defaults to 0.
*/
public function getVirtualCount()
{
return $this->_virtualCount;
}
/**
* @param int $value user-assigned number of items in data source
*/
public function setVirtualCount($value)
{
if (($value = TPropertyValue::ensureInteger($value)) < 0) {
$value = -1;
}
$this->_virtualCount = $value;
}
/**
* @return int number of pages, -1 if under custom paging mode and {@link setVirtualCount VirtualCount} is not set.
*/
public function getPageCount()
{
if ($this->_customPaging) {
if ($this->_virtualCount >= 0) {
return (int) (($this->_virtualCount + $this->_pageSize - 1) / $this->_pageSize);
} else {
return -1;
}
} else {
return (int) ((parent::getCount() + $this->_pageSize - 1) / $this->_pageSize);
}
}
/**
* @return bool whether the current page is the first page
*/
public function getIsFirstPage()
{
return $this->_currentPageIndex === 0;
}
/**
* @return bool whether the current page is the last page
*/
public function getIsLastPage()
{
return $this->_currentPageIndex === $this->getPageCount() - 1;
}
/**
* @return int the number of items in current page
*/
public function getCount()
{
if ($this->_customPaging) {
return parent::getCount();
} else {
if ($this->_currentPageIndex === $this->getPageCount() - 1) {
return parent::getCount() - $this->_pageSize * $this->_currentPageIndex;
} else {
return $this->_pageSize;
}
}
}
/**
* @return \Iterator iterator
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
if ($this->_customPaging) {
return parent::getIterator();
} else {
$data = $this->toArray();
return new \ArrayIterator($data);
}
}
/**
* Returns the item at the specified offset.
* This method is exactly the same as {@link offsetGet}.
* @param int $index the index of the item
* @throws TInvalidDataValueException if the index is out of the range
* @return mixed the item at the index
*/
public function itemAt($index)
{
if ($this->_customPaging) {
return parent::itemAt($index);
} else {
return parent::itemAt($this->_pageSize * $this->_currentPageIndex + $index);
}
}
/**
* @param mixed $item the item
* @return int the index of the item in the list (0 based), -1 if not found.
*/
public function indexOf($item)
{
$c = $this->getCount();
for ($i = 0; $i < $c; ++$i) {
if ($this->itemAt($i) === $item) {
return $i;
}
}
return -1;
}
/**
* Returns whether there is an item at the specified offset.
* This method is required by the interface \ArrayAccess.
* @param int $offset the offset to check on
* @return bool
*/
public function offsetExists($offset): bool
{
return ($offset >= 0 && $offset < $this->getCount());
}
/**
* Returns the item at the specified offset.
* This method is required by the interface \ArrayAccess.
* @param int $offset the offset to retrieve item.
* @throws TInvalidDataValueException if the offset is invalid
* @return mixed the item at the offset
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
return $this->itemAt($offset);
}
/**
* @return array the list of items in array
*/
public function toArray()
{
$c = $this->getCount();
$array = [];
for ($i = 0; $i < $c; ++$i) {
$array[$i] = $this->itemAt($i);
}
return $array;
}
}