TYPO3 CMS  TYPO3_7-6
PaginateController.php
Go to the documentation of this file.
1 <?php
3 
4 /* *
5  * This script is backported from the TYPO3 Flow package "TYPO3.Fluid". *
6  * *
7  * It is free software; you can redistribute it and/or modify it under *
8  * the terms of the GNU Lesser General Public License, either version 3 *
9  * of the License, or (at your option) any later version. *
10  * *
11  * *
12  * This script is distributed in the hope that it will be useful, but *
13  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
14  * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
15  * General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU Lesser General Public *
18  * License along with the script. *
19  * If not, see http://www.gnu.org/licenses/lgpl.html *
20  * *
21  * The TYPO3 project - inspiring people to share! *
22  * */
27 
32 {
36  protected $configuration = [
37  'itemsPerPage' => 10,
38  'insertAbove' => false,
39  'insertBelow' => true,
40  'maximumNumberOfLinks' => 99,
41  'addQueryStringMethod' => '',
42  'section' => ''
43  ];
44 
48  protected $objects;
49 
53  protected $currentPage = 1;
54 
58  protected $maximumNumberOfLinks = 99;
59 
63  protected $numberOfPages = 1;
64 
68  protected $displayRangeStart = null;
69 
73  protected $displayRangeEnd = null;
74 
78  public function initializeAction()
79  {
80  $this->objects = $this->widgetConfiguration['objects'];
81  ArrayUtility::mergeRecursiveWithOverrule($this->configuration, $this->widgetConfiguration['configuration'], false);
82  $itemsPerPage = (int)$this->configuration['itemsPerPage'];
83  $this->numberOfPages = $itemsPerPage > 0 ? ceil(count($this->objects) / $itemsPerPage) : 0;
84  $this->maximumNumberOfLinks = (int)$this->configuration['maximumNumberOfLinks'];
85  }
86 
91  public function indexAction($currentPage = 1)
92  {
93  // set current page
94  $this->currentPage = (int)$currentPage;
95  if ($this->currentPage < 1) {
96  $this->currentPage = 1;
97  }
98  if ($this->currentPage > $this->numberOfPages) {
99  // set $modifiedObjects to NULL if the page does not exist
100  $modifiedObjects = null;
101  } else {
102  // modify query
103  $itemsPerPage = (int)$this->configuration['itemsPerPage'];
104  $offset = 0;
105  if ($this->currentPage > 1) {
106  $offset = ((int)($itemsPerPage * ($this->currentPage - 1)));
107  }
108  $modifiedObjects = $this->prepareObjectsSlice($itemsPerPage, $offset);
109  }
110  $this->view->assign('contentArguments', [
111  $this->widgetConfiguration['as'] => $modifiedObjects
112  ]);
113  $this->view->assign('configuration', $this->configuration);
114  $this->view->assign('pagination', $this->buildPagination());
115  }
116 
123  protected function calculateDisplayRange()
124  {
126  if ($maximumNumberOfLinks > $this->numberOfPages) {
128  }
129  $delta = floor($maximumNumberOfLinks / 2);
130  $this->displayRangeStart = $this->currentPage - $delta;
131  $this->displayRangeEnd = $this->currentPage + $delta - ($maximumNumberOfLinks % 2 === 0 ? 1 : 0);
132  if ($this->displayRangeStart < 1) {
133  $this->displayRangeEnd -= $this->displayRangeStart - 1;
134  }
135  if ($this->displayRangeEnd > $this->numberOfPages) {
136  $this->displayRangeStart -= $this->displayRangeEnd - $this->numberOfPages;
137  }
138  $this->displayRangeStart = (int)max($this->displayRangeStart, 1);
139  $this->displayRangeEnd = (int)min($this->displayRangeEnd, $this->numberOfPages);
140  }
141 
148  protected function buildPagination()
149  {
150  $this->calculateDisplayRange();
151  $pages = [];
152  for ($i = $this->displayRangeStart; $i <= $this->displayRangeEnd; $i++) {
153  $pages[] = ['number' => $i, 'isCurrent' => $i === $this->currentPage];
154  }
155  $pagination = [
156  'pages' => $pages,
157  'current' => $this->currentPage,
158  'numberOfPages' => $this->numberOfPages,
159  'displayRangeStart' => $this->displayRangeStart,
160  'displayRangeEnd' => $this->displayRangeEnd,
161  'hasLessPages' => $this->displayRangeStart > 2,
162  'hasMorePages' => $this->displayRangeEnd + 1 < $this->numberOfPages
163  ];
164  if ($this->currentPage < $this->numberOfPages) {
165  $pagination['nextPage'] = $this->currentPage + 1;
166  }
167  if ($this->currentPage > 1) {
168  $pagination['previousPage'] = $this->currentPage - 1;
169  }
170  return $pagination;
171  }
172 
180  protected function prepareObjectsSlice($itemsPerPage, $offset)
181  {
182  if ($this->objects instanceof QueryResultInterface) {
183  $query = $this->objects->getQuery();
184  $query->setLimit($itemsPerPage);
185  if ($offset > 0) {
186  $query->setOffset($offset);
187  }
188  $modifiedObjects = $query->execute();
189  return $modifiedObjects;
190  } elseif ($this->objects instanceof ObjectStorage) {
191  $modifiedObjects = [];
192  $objectArray = $this->objects->toArray();
193  $endOfRange = min($offset + $itemsPerPage, count($objectArray));
194  for ($i = $offset; $i < $endOfRange; $i++) {
195  $modifiedObjects[] = $objectArray[$i];
196  }
197  return $modifiedObjects;
198  } elseif (is_array($this->objects)) {
199  $modifiedObjects = array_slice($this->objects, $offset, $itemsPerPage);
200  return $modifiedObjects;
201  } else {
202  throw new \InvalidArgumentException('The view helper "' . get_class($this)
203  . '" accepts as argument "QueryResultInterface", "\SplObjectStorage", "ObjectStorage" or an array. '
204  . 'given: ' . get_class($this->objects), 1385547291
205  );
206  }
207  }
208 }
static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=true, $includeEmptyValues=true, $enableUnsetFeature=true)