page = $page; $this->caption = $caption; $this->isCurrent = $isCurrent; $this->pageNumber = $pageNumber; $this->prefix = $prefix; $this->linkBuilder = $linkBuilder; $this->hint = $hint; $this->renderText = $renderText; } public function HasShortCut() { return isset($this->shortCut) && !is_null($this->shortCut); } public function GetShortCut() { return $this->shortCut; } public function SetShortCut($value) { $this->shortCut = $value; } function GetHint() { return $this->renderText ? $this->page->RenderText($this->hint) : $this->hint; } function GetPage() { return $this->page; } function IsCurrent() { return $this->isCurrent; } function GetPageCaption() { return $this->renderText ? $this->page->RenderText($this->caption) : $this->caption; } function GetPageLink() { if ($this->linkBuilder) { $result = $this->linkBuilder; if (isset($this->pageNumber)) $result->AddParameter($this->prefix . 'page', $this->pageNumber); else $result->RemoveParameter($this->prefix . 'page'); return $result->GetLink(); } return null; } } abstract class BasePageNavigator { public function __construct() { } public function AddCurrentPageParameters(&$linkBuilder) { } public function ProcessMessages() { } public function Accept($Renderer) { } public abstract function BuildPages(LinkBuilder $linkBuilder); } class AbstractPageNavigator { /** @var Page */ private $page; /** @var Dataset */ private $dataset; /** @var string */ private $name; /** @var PageNavigatorPage[] */ private $pages; /** @var string */ private $prefix; /** @var string */ private $caption; /** @var PageNavigator[] */ private $pageNavigatorList; /** @var integer */ private $currentPageNumber; /** @var array */ private $ignorePageNavigationOperations = array( OPERATION_PRINT_ALL //, OPERATION_EXCEL_EXPORT //, OPERATION_WORD_EXPORT //, OPERATION_XML_EXPORT //, OPERATION_CSV_EXPORT //, OPERATION_PDF_EXPORT ); function __construct($name, $page, $dataset, $caption, $pageNavigatorList, $prefix = null) { $this->name = $name; $this->page = $page; $this->dataset = $dataset; $this->pages = array(); $this->prefix = isset($prefix) ? $prefix : $name; $this->caption = $caption; $this->pages = null; $this->pageNavigatorList = $pageNavigatorList; } function GetName() { return $this->name; } function GetPagaNavigatorList() { return $this->pageNavigatorList; } function GetPage() { return $this->page; } function GetCaption() { return $this->caption; } function CurrentPageNumber() { return $this->currentPageNumber; } function GetPrefix() { return $this->prefix; } function GetPages() { assert(isset($this->pages)); return $this->pages; } function ApplyPageToDataset($currentPageNumber, Dataset $dataset) { } function FillPages(&$pages, $currentPage, $linkBuilder) { } function HasSetPageRequest() { return GetApplication()->IsGETValueSet($this->prefix . 'page'); } function GetPageFromRequest() { return GetApplication()->GetGETValue($this->prefix . 'page'); } public function NeedResetPage() { return false; } function SessionContainsStoredPage() { return GetApplication()->IsSessionVariableSet($this->prefix . 'page'); } function StorePageToSession() { GetApplication()->SetSessionVariable($this->prefix . 'page', $this->currentPageNumber); } function RestorePageFromSession() { $this->currentPageNumber = GetApplication()->GetSessionVariable($this->prefix . 'page'); } function ResetPageNumber() { GetApplication()->UnSetSessionVariable($this->prefix . 'page'); $this->currentPageNumber = null; } function ProcessMessages() { if ($this->HasSetPageRequest() && !$this->NeedResetPage()) { $this->currentPageNumber = $this->GetPageFromRequest(); $this->StorePageToSession(); } elseif (!$this->NeedResetPage() && $this->SessionContainsStoredPage()) { $this->RestorePageFromSession(); } else { $this->ResetPageNumber(); } if (!in_array(GetOperation(), $this->ignorePageNavigationOperations)) { $this->ApplyPageToDataset($this->currentPageNumber, $this->dataset); } } public function BuildPages(LinkBuilder $linkBuilder) { $this->pages = array(); $this->FillPages($this->pages, $this->currentPageNumber, $linkBuilder); } /** * @param LinkBuilder $linkBuilder */ function AddCurrentPageParameters(&$linkBuilder) { $linkBuilder->AddParameter($this->prefix . 'page', $this->CurrentPageNumber()); } /** * @param Renderer $Renderer */ function Accept($Renderer) { $Renderer->RenderCustomPageNavigator($this); } } class PageNavigator { private $name; /** @var Dataset */ private $dataset; private $rowsPerPage; private $pageNumber; private $pages; /** @var Page */ private $page; private $rowCount = null; private $pageCount = null; private $recordsPerPageValues; private $previosPageLink; private $nextPageLink; private $ignorePageNavigationOperations = array(OPERATION_PRINT_ALL, OPERATION_EXCEL_EXPORT, OPERATION_WORD_EXPORT, OPERATION_XML_EXPORT, OPERATION_CSV_EXPORT, OPERATION_PDF_EXPORT); private $defaultRowPerPage; function __construct($name, $page, $Dataset, $defaultRowPerPage = 20, $recordsPerPageValues = null) { $this->name = $name; $this->page = $page; $this->dataset = $Dataset; $this->pageNumber = 0; if ($recordsPerPageValues == null) $this->recordsPerPageValues = array(10, 20, 50, 100, 0); else $this->recordsPerPageValues = $recordsPerPageValues; $this->previosPageLink = null; $this->nextPageLink = null; } function GetRecordsPerPageValues() { $result = array(); foreach ($this->recordsPerPageValues as $value) $result[$value] = $value == 0 ? 'ALL' : $value; return $result; } public function GetRowsPerPage() { return $this->rowsPerPage; } function SetRowsPerPage($RowsPerPage) { $this->rowsPerPage = $RowsPerPage; $this->defaultRowPerPage = $RowsPerPage; } private function NeedResetPage() { $result = false; //(!GetApplication()->HasPostGetRequestParameters()); return $result; } function ResetPageNumber() { GetApplication()->UnSetSessionVariable($this->GetSessionPrefix() . 'page'); $this->pageNumber = 0; //GetApplication()->UnSetSessionVariable('recperpage'); //$this->rowsPerPage = $this->defaultRowPerPage; } private function GetSessionPrefix() { return $this->page->GetGrid()->GetId(); } function ProcessMessages() { if (GetApplication()->IsGETValueSet('page')) { $this->pageNumber = GetApplication()->GetGETValue('page') - 1; GetApplication()->SetSessionVariable($this->GetSessionPrefix() . 'page', $this->pageNumber); } elseif (!$this->NeedResetPage() && GetApplication()->IsSessionVariableSet($this->GetSessionPrefix() . 'page')) { $this->pageNumber = GetApplication()->GetSessionVariable($this->GetSessionPrefix() . 'page'); } else { $this->ResetPageNumber(); } if (GetApplication()->IsGETValueSet('recperpage')) { $this->rowsPerPage = GetApplication()->GetGETValue('recperpage'); GetApplication()->SetSessionVariable($this->GetSessionPrefix() . 'recperpage', $this->rowsPerPage); } elseif (GetApplication()->IsSessionVariableSet($this->GetSessionPrefix() . 'recperpage')) { $this->rowsPerPage = GetApplication()->GetSessionVariable($this->GetSessionPrefix() . 'recperpage'); } else $this->rowsPerPage = $this->defaultRowPerPage; if ($this->pageNumber >= $this->GetPageCount()) $this->pageNumber = $this->GetPageCount() - 1; elseif ($this->pageNumber < 0) $this->pageNumber = 0; if (!in_array(GetOperation(), $this->ignorePageNavigationOperations)) { if (($this->rowsPerPage != 0) && ($this->GetRowCount() != 0)) { $this->dataset->SetUpLimit($this->pageNumber * $this->rowsPerPage); $this->dataset->SetLimit($this->rowsPerPage); } } } public function GetPageCount() { if (!isset($this->pageCount)) { if ($this->rowsPerPage != 0) { $this->pageCount = floor($this->GetRowCount() / $this->rowsPerPage) + ((floor($this->GetRowCount() / $this->rowsPerPage) == ($this->GetRowCount() / $this->rowsPerPage)) ? 0 : 1); } else $this->pageCount = 1; } return $this->pageCount; } public function CurrentPageNumber() { return $this->pageNumber + 1; } public function GetRowCount() { if (!isset($this->rowCount)) $this->rowCount = $this->RetrieveRowCount(); return $this->rowCount; } /** * @return mixed|void */ protected function RetrieveRowCount() { return $this->dataset->GetTotalRowCount(); } function GetHintForPage($number, $shortCut = null) { $page = $number - 1; $rowCount = $this->rowCount; $rowsPerPage = $this->rowsPerPage; $startRecord = $page * $rowsPerPage + 1; $endRecord = min(array(($page + 1) * $rowsPerPage, $rowCount)); $result = sprintf($this->page->GetLocalizerCaptions()->GetMessageString('RecordsMtoKFromN'), $startRecord, $endRecord, $rowCount); if (isset($shortCut)) $result .= ";\n" . $shortCut; return $result; } function GetPageCountForPageSize($pageSize) { if ($pageSize != 0) { return floor($this->GetRowCount() / $pageSize) + ((floor($this->GetRowCount() / $pageSize) == ($this->GetRowCount() / $pageSize)) ? 0 : 1); } else return 1; } private function CreateNavigationPageSpacer() { return new PageNavigatorPage($this->page, '...', 1, 0, false); } private function CreateNavigatorPages($currentPage, $pageCount, $linkBuilder) { $nextPages = array(); $prevPages = array(); for ($i = $currentPage - 1; $i > max($currentPage - 2, 0); $i--) { $prevPage = new PageNavigatorPage($this->page, $i, $i, false, $linkBuilder, '', $this->GetHintForPage($i), false); $prevPages[] = $prevPage; if ($i = ($currentPage - 1)) $prevPage->SetShortCut('Ctrl+left'); } if ($currentPage - 10 > 1) { $prevPages[] = $this->CreateNavigationPageSpacer(); $prevPages[] = new PageNavigatorPage($this->page, $currentPage - 10, $currentPage - 10, false, $linkBuilder, '', $this->GetHintForPage($currentPage - 10), false); } if ($currentPage - 50 > 1) { $prevPages[] = $this->CreateNavigationPageSpacer(); $prevPages[] = new PageNavigatorPage($this->page, $currentPage - 50, $currentPage - 50, false, $linkBuilder, '', $this->GetHintForPage($currentPage - 50), false); } if ($currentPage - 100 > 1) { $prevPages[] = $this->CreateNavigationPageSpacer(); $prevPages[] = new PageNavigatorPage($this->page, $currentPage - 100, $currentPage - 100, false, $linkBuilder, '', $this->GetHintForPage($currentPage - 100), false); } if ($currentPage - 1 > 1) { if ($currentPage - 2 > 1) $prevPages[] = $this->CreateNavigationPageSpacer(); $prevPages[] = new PageNavigatorPage($this->page, '1', 1, false, $linkBuilder, '', $this->GetHintForPage(1), false);; } for ($i = $currentPage + 1; $i < min($currentPage + 2, $pageCount + 1); $i++) { $pageLink = new PageNavigatorPage($this->page, $i, $i, false, $linkBuilder, '', $this->GetHintForPage($i), false); $nextPages[] = $pageLink; if ($i = $currentPage + 1) $pageLink->SetShortCut('Ctrl+right'); } if ($currentPage + 10 < $pageCount) { $nextPages[] = $this->CreateNavigationPageSpacer(); $nextPages[] = new PageNavigatorPage($this->page, $currentPage + 10, $currentPage + 10, false, $linkBuilder, '', $this->GetHintForPage($currentPage + 10), false); } if ($currentPage + 50 < $pageCount) { $nextPages[] = $this->CreateNavigationPageSpacer(); $nextPages[] = new PageNavigatorPage($this->page, $currentPage + 50, $currentPage + 50, false, $linkBuilder, '', $this->GetHintForPage($currentPage + 50), false); } if ($currentPage + 100 < $pageCount) { $nextPages[] = $this->CreateNavigationPageSpacer(); $nextPages[] = new PageNavigatorPage($this->page, $currentPage + 100, $currentPage + 100, false, $linkBuilder, '', $this->GetHintForPage($currentPage + 100), false); } if ($currentPage + 1 < $pageCount) { if ($currentPage + 2 < $pageCount) $nextPages[] = $this->CreateNavigationPageSpacer(); $nextPages[] = new PageNavigatorPage($this->page, $pageCount, $pageCount, false, $linkBuilder, '', $this->GetHintForPage($pageCount), false); } $result = array(); for ($i = (count($prevPages) - 1); $i >= 0; $i--) $result[] = $prevPages[$i]; $result[] = new PageNavigatorPage($this->page, $currentPage, $currentPage, true, $linkBuilder, '', $this->GetHintForPage($currentPage), false); for ($i = 0; $i < count($nextPages); $i++) $result[] = $nextPages[$i]; return $result; } function HasPreviosPage() { return isset($this->previosPageLink); } function HasNextPage() { return isset($this->nextPageLink); } function NextPageLink() { return $this->nextPageLink; } function PreviosPageLink() { return $this->previosPageLink; } function BuildPages($linkBuilder) { $this->pages = array(); $this->FillPages($linkBuilder); } private function FillPages($linkBuilder) { $this->pages = $this->CreateNavigatorPages($this->CurrentPageNumber(), $this->GetPageCount(), $linkBuilder); } public function GetCurrentPageGetParameters() { $result = $this->page->CreateLinkBuilder(); return $result->GetParameters(); } function GetPages() { assert(isset($this->pages)); return $this->pages; } /** * @param LinkBuilder $linkBuilder */ function AddCurrentPageParameters(&$linkBuilder) { $linkBuilder->AddParameter('page', $this->CurrentPageNumber()); } /** * @param Renderer $renderer */ function Accept($renderer) { $renderer->RenderPageNavigator($this); } } class CustomPageNavigator extends AbstractPageNavigator { private $userPartitions; public $OnGetPartitions; public $OnGetPartitionCondition; private $allowViewAllRecords; private $navigationStyle; function __construct($name, $page, $dataset, $caption, $pageNavigatorList, $prefix = null) { parent::__construct($name, $page, $dataset, $caption, $prefix); $this->OnGetPartitions = new Event(); $this->OnGetPartitionCondition = new Event(); $this->userPartitions = null; $this->allowViewAllRecords = false; $this->navigationStyle = NS_LIST; } function GetPageFromRequest() { if (parent::HasSetPageRequest()) return parent::GetPageFromRequest(); else return null; } function DoOnGetPartitions() { $result = array(); $this->OnGetPartitions->Fire(array(&$result)); return $result; } function DoOnGetPartitionCondition($currentPageNumber) { $condition = ''; $this->OnGetPartitionCondition->Fire(array($currentPageNumber, &$condition)); return $condition; } function FillUserPartitions() { if (!isset($this->userPartitions)) $this->userPartitions = $this->DoOnGetPartitions(); } public function NeedResetPage() { $result = (GetApplication()->IsGETValueSet($this->GetPrefix() . 'page')) && (GetApplication()->GetGETValue($this->GetPrefix() . 'page')) == 'reset'; return $result; } function FillPages(&$pages, $currentPage, $linkBuilder) { $this->FillUserPartitions(); if (!isset($currentPage) || $currentPage == '') { $userPartitionsKeys = array_keys($this->userPartitions); if ($this->GetAllowViewAllRecords()) $currentPage = null; else $currentPage = $userPartitionsKeys[0]; } if ($this->GetAllowViewAllRecords()) $pages[] = new PageNavigatorPage( $this->GetPage(), $this->GetPage()->GetLocalizerCaptions()->GetMessageString('All'), 'reset', $currentPage == null, $linkBuilder, $this->GetPrefix(), '', false); foreach ($this->userPartitions as $partitionName => $partitionCaption) $pages[] = new PageNavigatorPage($this->GetPage(), $partitionCaption, $partitionName, ($currentPage != null) && $partitionName == $currentPage, $linkBuilder, $this->GetPrefix()); } /** * @param mixed $currentPageNumber * @param Dataset $dataset */ function ApplyPageToDataset($currentPageNumber, Dataset $dataset) { if (!isset($currentPageNumber) || $currentPageNumber == '') { $this->FillUserPartitions(); $userPartitionsKeys = array_keys($this->userPartitions); if ($this->GetAllowViewAllRecords()) $currentPageNumber = null; else $currentPageNumber = $userPartitionsKeys[0]; } if (isset($currentPageNumber)) { $condition = $this->DoOnGetPartitionCondition($currentPageNumber); if (isset($condition) && $condition != '') $dataset->AddCustomCondition($condition); } } function GetAllowViewAllRecords() { return $this->allowViewAllRecords; } function SetAllowViewAllRecords($value) { $this->allowViewAllRecords = $value; } function GetNavigationStyle() { return $this->navigationStyle; } function SetNavigationStyle($value) { $this->navigationStyle = $value; } } class CompositePageNavigator extends BasePageNavigator { /** @var Page */ private $page; /** @var BasePageNavigator[] */ private $pageNavigators; function __construct($page) { parent::__construct(); $this->page = $page; $this->pageNavigators = array(); } function AddPageNavigator($pageNavigator) { $this->pageNavigators[] = $pageNavigator; } function AddCurrentPageParameters(&$linkBuilder) { foreach ($this->pageNavigators as $pageNavigator) $pageNavigator->AddCurrentPageParameters($linkBuilder); } /** * @return LinkBuilder */ function CreateLinkBuilder() { return $this->page->CreateLinkBuilder(); } function ProcessMessages() { foreach ($this->pageNavigators as $pageNavigator) $pageNavigator->ProcessMessages(); $linkBuilder = $this->CreateLinkBuilder(); $this->BuildPages($linkBuilder); } /** * @param Renderer $renderer */ function Accept($renderer) { $renderer->RenderCompositePageNavigator($this); } function GetPageNavigators() { return $this->pageNavigators; } public function BuildPages(LinkBuilder $linkBuilder) { foreach ($this->pageNavigators as $pageNavigator) { $pageNavigator->AddCurrentPageParameters($linkBuilder); $pageNavigator->BuildPages($linkBuilder->CloneLinkBuilder()); } } }