2011-12-06 01:56:24 +01:00
|
|
|
<?php
|
|
|
|
/**
|
2012-01-23 18:19:27 +01:00
|
|
|
* GridFieldPaginator paginates the gridfields list and adds controlls to the
|
|
|
|
* bottom of the gridfield.
|
2011-12-06 01:56:24 +01:00
|
|
|
*
|
2012-04-12 08:02:46 +02:00
|
|
|
* @package framework
|
2011-12-06 01:56:24 +01:00
|
|
|
* @subpackage fields-relational
|
|
|
|
*/
|
|
|
|
class GridFieldPaginator implements GridField_HTMLProvider, GridField_DataManipulator, GridField_ActionProvider {
|
2012-01-23 18:19:27 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @var int
|
|
|
|
*/
|
2012-02-22 04:25:11 +01:00
|
|
|
protected $itemsPerPage = 15;
|
2011-12-06 01:56:24 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Which template to use for rendering
|
|
|
|
*
|
2012-01-23 18:19:27 +01:00
|
|
|
* @var string
|
2011-12-06 01:56:24 +01:00
|
|
|
*/
|
|
|
|
protected $itemClass = 'GridFieldPaginator_Row';
|
|
|
|
|
2012-03-09 02:32:16 +01:00
|
|
|
/**
|
2012-03-10 02:44:12 +01:00
|
|
|
* See {@link setThrowExceptionOnBadDataType()}
|
2012-03-09 02:32:16 +01:00
|
|
|
*/
|
|
|
|
protected $throwExceptionOnBadDataType = true;
|
|
|
|
|
2012-01-23 18:19:27 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param int $itemsPerPage - How many items should be displayed per page
|
|
|
|
*/
|
2012-03-05 13:30:07 +01:00
|
|
|
public function __construct($itemsPerPage=null) {
|
|
|
|
if($itemsPerPage) $this->itemsPerPage = $itemsPerPage;
|
2011-12-06 01:56:24 +01:00
|
|
|
}
|
2012-03-09 02:32:16 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Determine what happens when this component is used with a list that isn't {@link SS_Filterable}.
|
|
|
|
*
|
|
|
|
* - true: An exception is thrown
|
|
|
|
* - false: This component will be ignored - it won't make any changes to the GridField.
|
|
|
|
*
|
|
|
|
* By default, this is set to true so that it's clearer what's happening, but the predefined
|
|
|
|
* {@link GridFieldConfig} subclasses set this to false for flexibility.
|
|
|
|
*/
|
2012-03-10 02:44:12 +01:00
|
|
|
public function setThrowExceptionOnBadDataType($throwExceptionOnBadDataType) {
|
2012-03-09 02:32:16 +01:00
|
|
|
$this->throwExceptionOnBadDataType = $throwExceptionOnBadDataType;
|
|
|
|
}
|
2012-03-10 02:44:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* See {@link setThrowExceptionOnBadDataType()}
|
|
|
|
*/
|
|
|
|
public function getThrowExceptionOnBadDataType() {
|
|
|
|
return $this->throwExceptionOnBadDataType;
|
|
|
|
}
|
2012-03-09 02:32:16 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Check that this dataList is of the right data type.
|
|
|
|
* Returns false if it's a bad data type, and if appropriate, throws an exception.
|
|
|
|
*/
|
|
|
|
protected function checkDataType($dataList) {
|
|
|
|
if($dataList instanceof SS_Limitable) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
if($this->throwExceptionOnBadDataType) {
|
|
|
|
throw new LogicException(get_class($this) . " expects an SS_Limitable list to be passed to the GridField.");
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2011-12-06 01:56:24 +01:00
|
|
|
|
2012-01-23 18:19:27 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param GridField $gridField
|
|
|
|
* @return array
|
|
|
|
*/
|
2011-12-06 01:56:24 +01:00
|
|
|
public function getActions($gridField) {
|
2012-03-09 02:32:16 +01:00
|
|
|
if(!$this->checkDataType($gridField->getList())) return;
|
|
|
|
|
2011-12-06 01:56:24 +01:00
|
|
|
return array('paginate');
|
|
|
|
}
|
|
|
|
|
2012-01-23 18:19:27 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param GridField $gridField
|
|
|
|
* @param string $actionName
|
|
|
|
* @param string $arguments
|
|
|
|
* @param array $data
|
|
|
|
* @return void
|
|
|
|
*/
|
2011-12-06 01:56:24 +01:00
|
|
|
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
|
2012-03-09 02:32:16 +01:00
|
|
|
if(!$this->checkDataType($gridField->getList())) return;
|
|
|
|
|
2011-12-06 01:56:24 +01:00
|
|
|
if($actionName !== 'paginate') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$state = $gridField->State->GridFieldPaginator;
|
2012-03-07 04:01:19 +01:00
|
|
|
$state->currentPage = (int)$arguments;
|
2011-12-06 01:56:24 +01:00
|
|
|
}
|
2012-03-09 05:06:21 +01:00
|
|
|
|
|
|
|
protected $totalItems = 0;
|
2011-12-06 01:56:24 +01:00
|
|
|
|
2012-01-23 18:19:27 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param GridField $gridField
|
|
|
|
* @param SS_List $dataList
|
|
|
|
* @return SS_List
|
|
|
|
*/
|
2011-12-06 01:56:24 +01:00
|
|
|
public function getManipulatedData(GridField $gridField, SS_List $dataList) {
|
2012-03-09 02:32:16 +01:00
|
|
|
if(!$this->checkDataType($dataList)) return $dataList;
|
|
|
|
|
2012-09-06 13:43:34 +02:00
|
|
|
$this->totalItems = $dataList->count();
|
2012-03-09 05:06:21 +01:00
|
|
|
|
2012-03-07 04:01:19 +01:00
|
|
|
$state = $gridField->State->GridFieldPaginator;
|
2012-03-09 05:06:21 +01:00
|
|
|
if(!is_int($state->currentPage)) {
|
2012-03-07 04:01:19 +01:00
|
|
|
$state->currentPage = 1;
|
2012-03-09 05:06:21 +01:00
|
|
|
}
|
2012-03-07 04:01:19 +01:00
|
|
|
|
2012-03-09 02:02:37 +01:00
|
|
|
if(!($dataList instanceof SS_Limitable)) {
|
2011-12-06 01:56:24 +01:00
|
|
|
return $dataList;
|
|
|
|
}
|
2012-03-07 04:01:19 +01:00
|
|
|
if(!$state->currentPage) {
|
2012-03-09 02:02:37 +01:00
|
|
|
return $dataList->limit((int)$this->itemsPerPage);
|
2011-12-06 01:56:24 +01:00
|
|
|
}
|
2012-03-07 04:01:19 +01:00
|
|
|
$startRow = $this->itemsPerPage * ($state->currentPage - 1);
|
2012-03-09 02:02:37 +01:00
|
|
|
return $dataList->limit((int)$this->itemsPerPage, (int)$startRow);
|
2011-12-06 01:56:24 +01:00
|
|
|
}
|
|
|
|
|
2012-01-23 18:19:27 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param GridField $gridField
|
|
|
|
* @return array
|
|
|
|
*/
|
2011-12-06 01:56:24 +01:00
|
|
|
public function getHTMLFragments($gridField) {
|
2012-03-09 02:32:16 +01:00
|
|
|
if(!$this->checkDataType($gridField->getList())) return;
|
|
|
|
|
2012-03-07 04:01:19 +01:00
|
|
|
$state = $gridField->State->GridFieldPaginator;
|
|
|
|
if(!is_int($state->currentPage))
|
|
|
|
$state->currentPage = 1;
|
|
|
|
|
2012-03-05 03:28:25 +01:00
|
|
|
// Figure out which page and record range we're on
|
2012-03-09 05:06:21 +01:00
|
|
|
$totalRows = $this->totalItems;
|
2012-03-08 17:51:03 +01:00
|
|
|
if(!$totalRows) return array();
|
|
|
|
|
2012-05-18 01:18:55 +02:00
|
|
|
$totalPages = (int)ceil($totalRows/$this->itemsPerPage);
|
2012-03-07 02:47:57 +01:00
|
|
|
if($totalPages == 0)
|
|
|
|
$totalPages = 1;
|
2012-03-07 04:01:19 +01:00
|
|
|
$firstShownRecord = ($state->currentPage - 1) * $this->itemsPerPage + 1;
|
2012-03-07 02:47:57 +01:00
|
|
|
if($firstShownRecord > $totalRows)
|
|
|
|
$firstShownRecord = $totalRows;
|
2012-03-07 04:01:19 +01:00
|
|
|
$lastShownRecord = $state->currentPage * $this->itemsPerPage;
|
2012-03-05 03:28:25 +01:00
|
|
|
if($lastShownRecord > $totalRows)
|
|
|
|
$lastShownRecord = $totalRows;
|
2012-05-18 01:18:55 +02:00
|
|
|
|
|
|
|
// If there is only 1 page for all the records in list, we don't need to go further
|
|
|
|
// to sort out those first page, last page, pre and next pages, etc
|
|
|
|
// we are not render those in to the paginator.
|
|
|
|
if($totalPages === 1){
|
|
|
|
$forTemplate = new ArrayData(array(
|
|
|
|
'OnlyOnePage' => true,
|
|
|
|
'FirstShownRecord' => $firstShownRecord,
|
|
|
|
'LastShownRecord' => $lastShownRecord,
|
|
|
|
'NumRecords' => $totalRows
|
|
|
|
));
|
|
|
|
}else{
|
|
|
|
// First page button
|
|
|
|
$firstPage = new GridField_FormAction($gridField, 'pagination_first', 'First', 'paginate', 1);
|
|
|
|
$firstPage->addExtraClass('ss-gridfield-firstpage');
|
|
|
|
if($state->currentPage == 1)
|
|
|
|
$firstPage = $firstPage->performDisabledTransformation();
|
|
|
|
|
|
|
|
// Previous page button
|
|
|
|
$previousPageNum = $state->currentPage <= 1 ? 1 : $state->currentPage - 1;
|
|
|
|
$previousPage = new GridField_FormAction($gridField, 'pagination_prev', 'Previous', 'paginate', $previousPageNum);
|
|
|
|
$previousPage->addExtraClass('ss-gridfield-previouspage');
|
|
|
|
if($state->currentPage == 1)
|
|
|
|
$previousPage = $previousPage->performDisabledTransformation();
|
|
|
|
|
|
|
|
// Next page button
|
|
|
|
$nextPageNum = $state->currentPage >= $totalPages ? $totalPages : $state->currentPage + 1;
|
|
|
|
$nextPage = new GridField_FormAction($gridField, 'pagination_next', 'Next', 'paginate', $nextPageNum);
|
|
|
|
$nextPage->addExtraClass('ss-gridfield-nextpage');
|
|
|
|
if($state->currentPage == $totalPages)
|
|
|
|
$nextPage = $nextPage->performDisabledTransformation();
|
|
|
|
|
|
|
|
// Last page button
|
|
|
|
$lastPage = new GridField_FormAction($gridField, 'pagination_last', 'Last', 'paginate', $totalPages);
|
|
|
|
$lastPage->addExtraClass('ss-gridfield-lastpage');
|
|
|
|
if($state->currentPage == $totalPages)
|
|
|
|
$lastPage = $lastPage->performDisabledTransformation();
|
|
|
|
|
|
|
|
|
|
|
|
// Render in template
|
|
|
|
$forTemplate = new ArrayData(array(
|
|
|
|
'OnlyOnePage' => false,
|
|
|
|
'FirstPage' => $firstPage,
|
|
|
|
'PreviousPage' => $previousPage,
|
|
|
|
'CurrentPageNum' => $state->currentPage,
|
|
|
|
'NumPages' => $totalPages,
|
|
|
|
'NextPage' => $nextPage,
|
|
|
|
'LastPage' => $lastPage,
|
|
|
|
'FirstShownRecord' => $firstShownRecord,
|
|
|
|
'LastShownRecord' => $lastShownRecord,
|
|
|
|
'NumRecords' => $totalRows
|
|
|
|
));
|
|
|
|
}
|
2011-12-06 01:56:24 +01:00
|
|
|
return array(
|
|
|
|
'footer' => $forTemplate->renderWith('GridFieldPaginator_Row', array('Colspan'=>count($gridField->getColumns()))),
|
|
|
|
);
|
|
|
|
}
|
2012-01-23 18:19:27 +01:00
|
|
|
|
2012-03-05 12:12:36 +01:00
|
|
|
/**
|
|
|
|
* @param Int
|
|
|
|
*/
|
|
|
|
public function setItemsPerPage($num) {
|
|
|
|
$this->itemsPerPage = $num;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Int
|
|
|
|
*/
|
|
|
|
public function getItemsPerPage() {
|
|
|
|
return $this->itemsPerPage;
|
|
|
|
}
|
|
|
|
|
2011-12-06 01:56:24 +01:00
|
|
|
}
|