PageRenderTime 42ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Backend/Core/Engine/DataGridPaging.php

http://github.com/forkcms/forkcms
PHP | 316 lines | 179 code | 46 blank | 91 comment | 18 complexity | 7e4fcb55e5932d2046947a6dd217463e MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, MIT, AGPL-3.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. namespace Backend\Core\Engine;
  3. use Backend\Core\Language\Language as BackendLanguage;
  4. use iSpoonDatagridPaging;
  5. /**
  6. * This is our implementation of iSpoonDatagridPaging
  7. */
  8. final class DataGridPaging implements iSpoonDatagridPaging
  9. {
  10. /** @var int */
  11. private $currentPage;
  12. /** @var int */
  13. private $totalNumberOfPages;
  14. /** @var string */
  15. private $baseUrl;
  16. /** @var string */
  17. private $orderByColumn;
  18. /** @var string */
  19. private $sortingDirection;
  20. /** @var int */
  21. private $resultsPerPage;
  22. /** @var int */
  23. private $totalNumberOfResults;
  24. /** @var int */
  25. private $offset;
  26. /**
  27. * Builds & returns the pagination
  28. *
  29. * @param string $baseUrl
  30. * @param int $offset
  31. * @param string $orderByColumn The name of the column to sort on.
  32. * @param string $sortingDirection The sorting method, possible values are: asc, desc.
  33. * @param int $totalNumberOfResults
  34. * @param int $resultsPerPage The items per page.
  35. * @param bool $debug
  36. * @param string $compileDirectory
  37. *
  38. * @return string
  39. */
  40. public static function getContent(
  41. $baseUrl,
  42. $offset,
  43. $orderByColumn,
  44. $sortingDirection,
  45. $totalNumberOfResults,
  46. $resultsPerPage,
  47. $debug = true,
  48. $compileDirectory = null
  49. ) {
  50. return (new self(
  51. $baseUrl,
  52. $offset,
  53. $orderByColumn,
  54. $sortingDirection,
  55. $totalNumberOfResults,
  56. $resultsPerPage
  57. ))->getHtml($debug, $compileDirectory);
  58. }
  59. /**
  60. * @param string $baseUrl
  61. * @param int $offset
  62. * @param string|null $orderByColumn The name of the column to sort on.
  63. * @param string $sortingDirection The sorting method, possible values are: asc, desc.
  64. * @param int $totalNumberOfResults
  65. * @param int $resultsPerPage The items per page.
  66. */
  67. private function __construct(
  68. string $baseUrl,
  69. int $offset,
  70. $orderByColumn,
  71. string $sortingDirection,
  72. int $totalNumberOfResults,
  73. int $resultsPerPage
  74. ) {
  75. $this->baseUrl = $baseUrl;
  76. $this->offset = $offset;
  77. $this->orderByColumn = $orderByColumn;
  78. $this->sortingDirection = $sortingDirection;
  79. $this->resultsPerPage = $resultsPerPage;
  80. $this->totalNumberOfResults = $totalNumberOfResults;
  81. $this->currentPage = (int) ceil($offset / $resultsPerPage) + 1;
  82. $this->totalNumberOfPages = (int) ceil($totalNumberOfResults / $resultsPerPage);
  83. }
  84. /**
  85. * @param bool $debug
  86. * @param string|null $compileDirectory
  87. *
  88. * @return string
  89. */
  90. public function getHtml($debug = true, string $compileDirectory = null)
  91. {
  92. // if there is just one page we don't need paging
  93. if ($this->totalNumberOfResults < $this->resultsPerPage) {
  94. return '';
  95. }
  96. // load template
  97. $tpl = new \SpoonTemplate();
  98. // compile directory
  99. $tpl->setCompileDirectory($compileDirectory ?? __DIR__);
  100. // force compiling
  101. $tpl->setForceCompile((bool) $debug);
  102. $tpl->assign('pagination', $this->getTemplateData());
  103. $tpl->assign('previousLabel', BackendLanguage::lbl('PreviousPage'));
  104. $tpl->assign('nextLabel', BackendLanguage::lbl('NextPage'));
  105. $tpl->assign('goToLabel', BackendLanguage::lbl('GoToPage'));
  106. return $tpl->getContent(BACKEND_CORE_PATH . '/Layout/Templates/DatagridPaging.tpl');
  107. }
  108. /**
  109. * @param int $offset
  110. *
  111. * @return string
  112. */
  113. private function getUrlForOffset(int $offset): string
  114. {
  115. return str_replace(
  116. ['[offset]', '[order]', '[sort]'],
  117. [$offset, $this->orderByColumn, $this->sortingDirection],
  118. $this->baseUrl
  119. );
  120. }
  121. /**
  122. * @return array
  123. */
  124. private function getTemplateData(): array
  125. {
  126. return [
  127. 'num_pages' => $this->totalNumberOfPages,
  128. 'current_page' => $this->currentPage,
  129. 'multiple_pages' => $this->totalNumberOfPages !== 1,
  130. 'show_previous' => $this->showPreviousLink(),
  131. 'previous_url' => $this->getPreviousLink(),
  132. 'first' => $this->getFirstPages(),
  133. 'pages' => $this->getPages($this->getPagesStart(), $this->getPagesEnd()),
  134. 'last' => $this->getLastPages(),
  135. 'show_next' => $this->showNextLink(),
  136. 'next_url' => $this->getNextLink(),
  137. ];
  138. }
  139. /**
  140. * @return bool
  141. */
  142. private function showNextLink(): bool
  143. {
  144. return $this->currentPage < $this->totalNumberOfPages;
  145. }
  146. /**
  147. * @return string
  148. */
  149. private function getNextLink(): string
  150. {
  151. if (!$this->showNextLink()) {
  152. return '';
  153. }
  154. return $this->getUrlForOffset($this->offset + $this->resultsPerPage);
  155. }
  156. /**
  157. * @return bool
  158. */
  159. private function showPreviousLink(): bool
  160. {
  161. return $this->currentPage > 1;
  162. }
  163. /**
  164. * @return string
  165. */
  166. private function getPreviousLink(): string
  167. {
  168. if (!$this->showPreviousLink()) {
  169. return '';
  170. }
  171. return $this->getUrlForOffset($this->offset - $this->resultsPerPage);
  172. }
  173. /**
  174. * @return int
  175. */
  176. private function getPagesStart(): int
  177. {
  178. // as long as we have more then 5 pages and are 5 pages from the end we should show all pages till the end
  179. if ($this->currentPage > 5 && $this->currentPage >= ($this->totalNumberOfPages - 4)) {
  180. if ($this->totalNumberOfPages === 6) {
  181. return 1;
  182. }
  183. return $this->totalNumberOfPages > 7 ? $this->totalNumberOfPages - 5 : $this->totalNumberOfPages - 6;
  184. }
  185. if ($this->currentPage <= 5) {
  186. return 1;
  187. }
  188. return $this->currentPage - 2;
  189. }
  190. /**
  191. * @return int
  192. */
  193. private function getPagesEnd(): int
  194. {
  195. // as long as we have more then 5 pages and are 5 pages from the end we should show all pages till the end
  196. if ($this->currentPage > 5 && $this->currentPage >= ($this->totalNumberOfPages - 4)) {
  197. return $this->totalNumberOfPages;
  198. }
  199. if ($this->currentPage <= 5) {
  200. if ($this->totalNumberOfPages === 7) {
  201. // when we have 7 pages, show 7 as end
  202. return 7;
  203. }
  204. if ($this->totalNumberOfPages <= 6) {
  205. // when we have less then 6 pages, show the maximum page
  206. return $this->totalNumberOfPages;
  207. }
  208. return 6;
  209. }
  210. return $this->currentPage + 2;
  211. }
  212. /**
  213. * @return bool
  214. */
  215. private function showFirstPages(): bool
  216. {
  217. if ($this->currentPage > 5 && $this->currentPage >= ($this->totalNumberOfPages - 4)) {
  218. return $this->totalNumberOfPages > 7;
  219. }
  220. return $this->currentPage > 5;
  221. }
  222. /**
  223. * @return bool
  224. */
  225. private function showLastPages(): bool
  226. {
  227. if ($this->currentPage <= 5) {
  228. return $this->totalNumberOfPages > 7;
  229. }
  230. return false;
  231. }
  232. /**
  233. * @return array
  234. */
  235. private function getFirstPages(): array
  236. {
  237. if (!$this->showFirstPages()) {
  238. return [];
  239. }
  240. return $this->getPages(1, 2);
  241. }
  242. /**
  243. * @param int $start
  244. * @param int $end
  245. *
  246. * @return array
  247. */
  248. private function getPages(int $start, int $end): array
  249. {
  250. $pages = [];
  251. for ($i = $start; $i <= $end; ++$i) {
  252. $pages[] = [
  253. 'url' => $this->getUrlForOffset($this->resultsPerPage * $i - $this->resultsPerPage),
  254. 'label' => $i,
  255. 'current' => $i === $this->currentPage,
  256. ];
  257. }
  258. return $pages;
  259. }
  260. /**
  261. * @return array
  262. */
  263. private function getLastPages(): array
  264. {
  265. if (!$this->showLastPages()) {
  266. return [];
  267. }
  268. return $this->getPages($this->totalNumberOfPages - 1, $this->totalNumberOfPages);
  269. }
  270. }