]> git.mxchange.org Git - friendica.git/blob - src/Content/Pager.php
Misspelling in use statement
[friendica.git] / src / Content / Pager.php
1 <?php
2
3 namespace Friendica\Content;
4
5 use Friendica\Core\L10n;
6
7 /**
8  * The Pager has two very different output, Minimal and Full, see renderMinimal() and renderFull() for more details.
9  *
10  * @author Hypolite Petovan <mrpetovan@gmail.com>
11  */
12 class Pager
13 {
14         /**
15          * @var integer
16          */
17         private $page = 1;
18         /**
19          * @var integer
20          */
21         private $itemsPerPage = 50;
22
23         /**
24          * @var string
25          */
26         private $baseQueryString = '';
27
28         /**
29          * Instantiates a new Pager with the base parameters.
30          *
31          * Guesses the page number from the GET parameter 'page'.
32          *
33          * @param string  $queryString  The query string of the current page
34          * @param integer $itemsPerPage An optional number of items per page to override the default value
35          */
36         public function __construct($queryString, $itemsPerPage = 50)
37         {
38                 $this->setQueryString($queryString);
39                 $this->setItemsPerPage($itemsPerPage);
40                 $this->setPage(defaults($_GET, 'page', 1));
41         }
42
43         /**
44          * Returns the start offset for a LIMIT clause. Starts at 0.
45          *
46          * @return integer
47          */
48         public function getStart()
49         {
50                 return max(0, ($this->page * $this->itemsPerPage) - $this->itemsPerPage);
51         }
52
53         /**
54          * Returns the number of items per page
55          *
56          * @return integer
57          */
58         public function getItemsPerPage()
59         {
60                 return $this->itemsPerPage;
61         }
62
63         /**
64          * Returns the current page number
65          *
66          * @return type
67          */
68         public function getPage()
69         {
70                 return $this->page;
71         }
72
73         /**
74          * Returns the base query string.
75          *
76          * Warning: this isn't the same value as passed to the constructor.
77          * See setQueryString() for the inventory of transformations
78          *
79          * @see setBaseQuery()
80          * @return string
81          */
82         public function getBaseQueryString()
83         {
84                 return $this->baseQueryString;
85         }
86
87         /**
88          * Sets the number of items per page, 1 minimum.
89          *
90          * @param integer $itemsPerPage
91          */
92         public function setItemsPerPage($itemsPerPage)
93         {
94                 $this->itemsPerPage = max(1, intval($itemsPerPage));
95         }
96
97         /**
98          * Sets the current page number. Starts at 1.
99          *
100          * @param integer $page
101          */
102         public function setPage($page)
103         {
104                 $this->page = max(1, intval($page));
105         }
106
107         /**
108          * Sets the base query string from a full query string.
109          *
110          * Strips the 'page' parameter, and remove the 'q=' string for some reason.
111          *
112          * @param string $queryString
113          */
114         public function setQueryString($queryString)
115         {
116                 $stripped = preg_replace('/([&?]page=[0-9]*)/', '', $queryString);
117
118                 $stripped = str_replace('q=', '', $stripped);
119                 $stripped = trim($stripped, '/');
120
121                 $this->baseQueryString = $stripped;
122         }
123
124         /**
125          * Ensures the provided URI has its query string punctuation in order.
126          *
127          * @param string $uri
128          * @return string
129          */
130         private function ensureQueryParameter($uri)
131         {
132                 if (strpos($uri, '?') === false && ($pos = strpos($uri, '&')) !== false) {
133                         $uri = substr($uri, 0, $pos) . '?' . substr($uri, $pos + 1);
134                 }
135
136                 return $uri;
137         }
138
139         /**
140          * @brief Minimal pager (newer/older)
141          *
142          * This mode is intended for reverse chronological pages and presents only two links, newer (previous) and older (next).
143          * The itemCount is the number of displayed items. If no items are displayed, the older button is disabled.
144          *
145          * Example usage:
146          *
147          * $pager = new Pager($a->query_string);
148          *
149          * $params = ['order' => ['sort_field' => true], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
150          * $items = DBA::toArray(DBA::select($table, $fields, $condition, $params));
151          *
152          * $html = $pager->renderMinimal(count($items));
153          *
154          * @param integer $itemCount The number of displayed items on the page
155          * @return string HTML string of the pager
156          */
157         public function renderMinimal($itemCount)
158         {
159                 $displayedItemCount = max(0, intval($itemCount));
160
161                 $data = [
162                         'class' => 'pager',
163                         'prev'  => [
164                                 'url'   => $this->ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() - 1)),
165                                 'text'  => L10n::t('newer'),
166                                 'class' => 'previous' . ($this->getPage() == 1 ? ' disabled' : '')
167                         ],
168                         'next'  => [
169                                 'url'   => $this->ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() + 1)),
170                                 'text'  => L10n::t('older'),
171                                 'class' =>  'next' . ($displayedItemCount <= 0 ? ' disabled' : '')
172                         ]
173                 ];
174
175                 $tpl = get_markup_template('paginate.tpl');
176                 return replace_macros($tpl, ['pager' => $data]);
177         }
178
179         /**
180          * @brief Full pager (first / prev / 1 / 2 / ... / 14 / 15 / next / last)
181          *
182          * This mode presents page numbers as well as first, previous, next and last links.
183          * The itemCount is the total number of items including those not displayed.
184          *
185          * Example usage:
186          *
187          * $total = DBA::count($table, $condition);
188          *
189          * $pager = new Pager($a->query_string, $total);
190          *
191          * $params = ['limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
192          * $items = DBA::toArray(DBA::select($table, $fields, $condition, $params));
193          *
194          * $html = $pager->renderFull();
195          *
196          * @param integer $itemCount The total number of items including those note displayed on the page
197          * @return string HTML string of the pager
198          */
199         public function renderFull($itemCount)
200         {
201                 $totalItemCount = max(0, intval($itemCount));
202
203                 $data = [];
204
205                 $data['class'] = 'pagination';
206                 if ($totalItemCount > $this->getItemsPerPage()) {
207                         $data['first'] = [
208                                 'url'   => $this->ensureQueryParameter($this->baseQueryString . '&page=1'),
209                                 'text'  => L10n::t('first'),
210                                 'class' => $this->getPage() == 1 ? 'disabled' : ''
211                         ];
212                         $data['prev'] = [
213                                 'url'   => $this->ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() - 1)),
214                                 'text'  => L10n::t('prev'),
215                                 'class' => $this->getPage() == 1 ? 'disabled' : ''
216                         ];
217
218                         $numpages = $totalItemCount / $this->getItemsPerPage();
219
220                         $numstart = 1;
221                         $numstop = $numpages;
222
223                         // Limit the number of displayed page number buttons.
224                         if ($numpages > 8) {
225                                 $numstart = (($this->getPage() > 4) ? ($this->getPage() - 4) : 1);
226                                 $numstop = (($this->getPage() > ($numpages - 7)) ? $numpages : ($numstart + 8));
227                         }
228
229                         $pages = [];
230
231                         for ($i = $numstart; $i <= $numstop; $i++) {
232                                 if ($i == $this->getPage()) {
233                                         $pages[$i] = [
234                                                 'url'   => '#',
235                                                 'text'  => $i,
236                                                 'class' => 'current active'
237                                         ];
238                                 } else {
239                                         $pages[$i] = [
240                                                 'url'   => $this->ensureQueryParameter($this->baseQueryString . '&page=' . $i),
241                                                 'text'  => $i,
242                                                 'class' => 'n'
243                                         ];
244                                 }
245                         }
246
247                         if (($totalItemCount % $this->getItemsPerPage()) != 0) {
248                                 if ($i == $this->getPage()) {
249                                         $pages[$i] = [
250                                                 'url'   => '#',
251                                                 'text'  => $i,
252                                                 'class' => 'current active'
253                                         ];
254                                 } else {
255                                         $pages[$i] = [
256                                                 'url'   => $this->ensureQueryParameter($this->baseQueryString . '&page=' . $i),
257                                                 'text'  => $i,
258                                                 'class' => 'n'
259                                         ];
260                                 }
261                         }
262
263                         $data['pages'] = $pages;
264
265                         $lastpage = (($numpages > intval($numpages)) ? intval($numpages)+1 : $numpages);
266
267                         $data['next'] = [
268                                 'url'   => $this->ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() + 1)),
269                                 'text'  => L10n::t('next'),
270                                 'class' => $this->getPage() == $lastpage ? 'disabled' : ''
271                         ];
272                         $data['last'] = [
273                                 'url'   => $this->ensureQueryParameter($this->baseQueryString . '&page=' . $lastpage),
274                                 'text'  => L10n::t('last'),
275                                 'class' => $this->getPage() == $lastpage ? 'disabled' : ''
276                         ];
277                 }
278
279                 $tpl = get_markup_template('paginate.tpl');
280                 return replace_macros($tpl, ['pager' => $data]);
281         }
282 }