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