TYPO3 CMS  TYPO3_8-7
PaginateController.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
20 
25 {
29  protected $configuration = [
30  'itemsPerPage' => 10,
31  'insertAbove' => false,
32  'insertBelow' => true,
33  'maximumNumberOfLinks' => 99,
34  'addQueryStringMethod' => '',
35  'section' => ''
36  ];
37 
41  protected $objects;
42 
46  protected $currentPage = 1;
47 
51  protected $maximumNumberOfLinks = 99;
52 
56  protected $numberOfPages = 1;
57 
61  protected $displayRangeStart = null;
62 
66  protected $displayRangeEnd = null;
67 
71  public function initializeAction()
72  {
73  $this->objects = $this->widgetConfiguration['objects'];
74  ArrayUtility::mergeRecursiveWithOverrule($this->configuration, $this->widgetConfiguration['configuration'], false);
75  $itemsPerPage = (int)$this->configuration['itemsPerPage'];
76  $this->numberOfPages = $itemsPerPage > 0 ? ceil(count($this->objects) / $itemsPerPage) : 0;
77  $this->maximumNumberOfLinks = (int)$this->configuration['maximumNumberOfLinks'];
78  }
79 
83  public function indexAction($currentPage = 1)
84  {
85  // set current page
86  $this->currentPage = (int)$currentPage;
87  if ($this->currentPage < 1) {
88  $this->currentPage = 1;
89  }
90  if ($this->currentPage > $this->numberOfPages) {
91  // set $modifiedObjects to NULL if the page does not exist
92  $modifiedObjects = null;
93  } else {
94  // modify query
95  $itemsPerPage = (int)$this->configuration['itemsPerPage'];
96  $offset = 0;
97  if ($this->currentPage > 1) {
98  $offset = ((int)($itemsPerPage * ($this->currentPage - 1)));
99  }
100  $modifiedObjects = $this->prepareObjectsSlice($itemsPerPage, $offset);
101  }
102  $this->view->assign('contentArguments', [
103  $this->widgetConfiguration['as'] => $modifiedObjects
104  ]);
105  $this->view->assign('configuration', $this->configuration);
106  $this->view->assign('pagination', $this->buildPagination());
107  }
108 
113  protected function calculateDisplayRange()
114  {
116  if ($maximumNumberOfLinks > $this->numberOfPages) {
118  }
119  $delta = floor($maximumNumberOfLinks / 2);
120  $this->displayRangeStart = $this->currentPage - $delta;
121  $this->displayRangeEnd = $this->currentPage + $delta - ($maximumNumberOfLinks % 2 === 0 ? 1 : 0);
122  if ($this->displayRangeStart < 1) {
123  $this->displayRangeEnd -= $this->displayRangeStart - 1;
124  }
125  if ($this->displayRangeEnd > $this->numberOfPages) {
126  $this->displayRangeStart -= $this->displayRangeEnd - $this->numberOfPages;
127  }
128  $this->displayRangeStart = (int)max($this->displayRangeStart, 1);
129  $this->displayRangeEnd = (int)min($this->displayRangeEnd, $this->numberOfPages);
130  }
131 
138  protected function buildPagination()
139  {
140  $this->calculateDisplayRange();
141  $pages = [];
142  for ($i = $this->displayRangeStart; $i <= $this->displayRangeEnd; $i++) {
143  $pages[] = ['number' => $i, 'isCurrent' => $i === $this->currentPage];
144  }
145  $pagination = [
146  'pages' => $pages,
147  'current' => $this->currentPage,
148  'numberOfPages' => $this->numberOfPages,
149  'displayRangeStart' => $this->displayRangeStart,
150  'displayRangeEnd' => $this->displayRangeEnd,
151  'hasLessPages' => $this->displayRangeStart > 2,
152  'hasMorePages' => $this->displayRangeEnd + 1 < $this->numberOfPages
153  ];
154  if ($this->currentPage < $this->numberOfPages) {
155  $pagination['nextPage'] = $this->currentPage + 1;
156  }
157  if ($this->currentPage > 1) {
158  $pagination['previousPage'] = $this->currentPage - 1;
159  }
160  return $pagination;
161  }
162 
170  protected function prepareObjectsSlice($itemsPerPage, $offset)
171  {
172  if ($this->objects instanceof QueryResultInterface) {
173  $query = $this->objects->getQuery();
174  $query->setLimit($itemsPerPage);
175  if ($offset > 0) {
176  $query->setOffset($offset);
177  }
178  $modifiedObjects = $query->execute();
179  return $modifiedObjects;
180  }
181  if ($this->objects instanceof ObjectStorage) {
182  $modifiedObjects = [];
183  $objectArray = $this->objects->toArray();
184  $endOfRange = min($offset + $itemsPerPage, count($objectArray));
185  for ($i = $offset; $i < $endOfRange; $i++) {
186  $modifiedObjects[] = $objectArray[$i];
187  }
188  return $modifiedObjects;
189  }
190  if (is_array($this->objects)) {
191  $modifiedObjects = array_slice($this->objects, $offset, $itemsPerPage);
192  return $modifiedObjects;
193  }
194  throw new \InvalidArgumentException(
195  'The view helper "' . get_class($this)
196  . '" accepts as argument "QueryResultInterface", "\SplObjectStorage", "ObjectStorage" or an array. '
197  . 'given: ' . get_class($this->objects),
198  1385547291
199  );
200  }
201 }
static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=true, $includeEmptyValues=true, $enableUnsetFeature=true)