Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

pagination.php

Zuletzt modifiziert: 02.04.2025, 15:01 - Dateigröße: 14.45 KiB


001  <?php
002  /**
003  *
004  * This file is part of the phpBB Forum Software package.
005  *
006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
007  * @license GNU General Public License, version 2 (GPL-2.0)
008  *
009  * For full copyright and license information, please see
010  * the docs/CREDITS.txt file.
011  *
012  */
013   
014  namespace phpbb;
015   
016  class pagination
017  {
018      /** @var \phpbb\template\template */
019      protected $template;
020   
021      /** @var \phpbb\user */
022      protected $user;
023   
024      /** @var \phpbb\controller\helper */
025      protected $helper;
026   
027      /** @var \phpbb\event\dispatcher_interface */
028      protected $phpbb_dispatcher;
029   
030      /**
031      * Constructor
032      *
033      * @param    \phpbb\template\template            $template
034      * @param    \phpbb\user                            $user
035      * @param    \phpbb\controller\helper            $helper
036      * @param    \phpbb\event\dispatcher_interface    $phpbb_dispatcher
037      */
038      public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\controller\helper $helper, \phpbb\event\dispatcher_interface $phpbb_dispatcher)
039      {
040          $this->template = $template;
041          $this->user = $user;
042          $this->helper = $helper;
043          $this->phpbb_dispatcher = $phpbb_dispatcher;
044      }
045   
046      /**
047      * Generate a pagination link based on the url and the page information
048      *
049      * @param string|array $base_url is url prepended to all links generated within the function
050      *                            If you use page numbers inside your controller route, base_url should contains a placeholder (%d)
051      *                            for the page. Also be sure to specify the pagination path information into the start_name argument
052      * @param string $on_page is the page for which we want to generate the link
053      * @param string $start_name is the name of the parameter containing the first item of the given page (example: start=20)
054      *                            If you use page numbers inside your controller route, start name should be the string
055      *                            that should be removed for the first page (example: /page/%d)
056      * @param int $per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce
057      * @return string URL for the requested page
058      */
059      protected function generate_page_link($base_url, $on_page, $start_name, $per_page)
060      {
061          // A listener can set this variable to the new pagination URL
062          // to override the generate_page_link() function generated value
063          $generate_page_link_override = false;
064   
065          /**
066          * Execute code and/or override generate_page_link()
067          *
068          * To override the generate_page_link() function generated value
069          * set $generate_page_link_override to the new URL value
070          *
071          * @event core.pagination_generate_page_link
072          * @var string|array base_url is url prepended to all links generated within the function
073          *                            If you use page numbers inside your controller route, base_url should contains a placeholder (%d)
074          *                            for the page. Also be sure to specify the pagination path information into the start_name argument
075          * @var string on_page is the page for which we want to generate the link
076          * @var string start_name is the name of the parameter containing the first item of the given page (example: start=20)
077          *                            If you use page numbers inside your controller route, start name should be the string
078          *                            that should be removed for the first page (example: /page/%d)
079          * @var int per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce
080          * @var bool|string generate_page_link_override Shall we return custom pagination link (string URL) or not (false)
081          * @since 3.1.0-RC5
082          */
083          $vars = array('base_url', 'on_page', 'start_name', 'per_page', 'generate_page_link_override');
084          extract($this->phpbb_dispatcher->trigger_event('core.pagination_generate_page_link', compact($vars)));
085   
086          if ($generate_page_link_override)
087          {
088              return $generate_page_link_override;
089          }
090   
091          if (!is_string($base_url))
092          {
093              if (is_array($base_url['routes']))
094              {
095                  $route = ($on_page > 1) ? $base_url['routes'][1] : $base_url['routes'][0];
096              }
097              else
098              {
099                  $route = $base_url['routes'];
100              }
101              $params = (isset($base_url['params'])) ? $base_url['params'] : array();
102              $is_amp = (isset($base_url['is_amp'])) ? $base_url['is_amp'] : true;
103              $session_id = (isset($base_url['session_id'])) ? $base_url['session_id'] : false;
104   
105              if ($on_page > 1 || !is_array($base_url['routes']))
106              {
107                  $params[$start_name] = (int) $on_page;
108              }
109   
110              return $this->helper->route($route, $params, $is_amp, $session_id);
111          }
112          else
113          {
114              $url_delim = (strpos($base_url, '?') === false) ? '?' : ((strpos($base_url, '?') === strlen($base_url) - 1) ? '' : '&amp;');
115              return ($on_page > 1) ? $base_url . $url_delim . $start_name . '=' . (($on_page - 1) * $per_page) : $base_url;
116          }
117      }
118   
119      /**
120      * Generate template rendered pagination
121      * Allows full control of rendering of pagination with the template
122      *
123      * @param string|array $base_url is url prepended to all links generated within the function
124      *                            If you use page numbers inside your controller route, base_url should contains a placeholder (%d)
125      *                            for the page. Also be sure to specify the pagination path information into the start_name argument
126      * @param string $block_var_name is the name assigned to the pagination data block within the template (example: <!-- BEGIN pagination -->)
127      * @param string $start_name is the name of the parameter containing the first item of the given page (example: start=20)
128      *                            If you use page numbers inside your controller route, start name should be the string
129      *                            that should be removed for the first page (example: /page/%d)
130      * @param int $num_items the total number of items, posts, etc., used to determine the number of pages to produce
131      * @param int $per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce
132      * @param int $start the item which should be considered currently active, used to determine the page we're on
133      * @param bool $reverse_count determines whether we weight display of the list towards the start (false) or end (true) of the list
134      * @param bool $ignore_on_page decides whether we enable an active (unlinked) item, used primarily for embedded lists
135      * @return void
136      */
137      public function generate_template_pagination($base_url, $block_var_name, $start_name, $num_items, $per_page, $start = 1, $reverse_count = false, $ignore_on_page = false)
138      {
139          if (empty($base_url))
140          {
141              return;
142          }
143   
144          $total_pages = ceil($num_items / $per_page);
145          $on_page = $this->get_on_page($per_page, $start);
146          $u_previous_page = $u_next_page = '';
147   
148          if ($total_pages > 1)
149          {
150              if ($reverse_count)
151              {
152                  $start_page = ($total_pages > 5) ? $total_pages - 4 : 1;
153                  $end_page = $total_pages;
154              }
155              else
156              {
157                  // What we're doing here is calculating what the "start" and "end" pages should be. We
158                  // do this by assuming pagination is "centered" around the currently active page with
159                  // the three previous and three next page links displayed. Anything more than that and
160                  // we display the ellipsis, likewise anything less.
161                  //
162                  // $start_page is the page at which we start creating the list. When we have five or less
163                  // pages we start at page 1 since there will be no ellipsis displayed. Anymore than that
164                  // and we calculate the start based on the active page. This is the min/max calculation.
165                  // First (max) would we end up starting on a page less than 1? Next (min) would we end
166                  // up starting so close to the end that we'd not display our minimum number of pages.
167                  //
168                  // $end_page is the last page in the list to display. Like $start_page we use a min/max to
169                  // determine this number. Again at most five pages? Then just display them all. More than
170                  // five and we first (min) determine whether we'd end up listing more pages than exist.
171                  // We then (max) ensure we're displaying the minimum number of pages.
172                  $start_page = ($total_pages > 5) ? min(max(1, $on_page - 2), $total_pages - 4) : 1;
173                  $end_page = ($total_pages > 5) ? max(min($total_pages, $on_page + 2), 5) : $total_pages;
174              }
175   
176              if ($on_page != 1)
177              {
178                  $u_previous_page = $this->generate_page_link($base_url, $on_page - 1, $start_name, $per_page);
179   
180                  $this->template->assign_block_vars($block_var_name, array(
181                      'PAGE_NUMBER'    => '',
182                      'PAGE_URL'        => $u_previous_page,
183                      'S_IS_CURRENT'    => false,
184                      'S_IS_PREV'        => true,
185                      'S_IS_NEXT'        => false,
186                      'S_IS_ELLIPSIS'    => false,
187                  ));
188              }
189   
190              // This do...while exists purely to negate the need for start and end assign_block_vars, i.e.
191              // to display the first and last page in the list plus any ellipsis. We use this loop to jump
192              // around a little within the list depending on where we're starting (and ending).
193              $at_page = 1;
194              do
195              {
196                  // We decide whether to display the ellipsis during the loop. The ellipsis is always
197                  // displayed as either the second or penultimate item in the list. So are we at either
198                  // of those points and of course do we even need to display it, i.e. is the list starting
199                  // on at least page 3 and ending three pages before the final item.
200                  $this->template->assign_block_vars($block_var_name, array(
201                      'PAGE_NUMBER'    => $at_page,
202                      'PAGE_URL'        => $this->generate_page_link($base_url, $at_page, $start_name, $per_page),
203                      'S_IS_CURRENT'    => (!$ignore_on_page && $at_page == $on_page),
204                      'S_IS_NEXT'        => false,
205                      'S_IS_PREV'        => false,
206                      'S_IS_ELLIPSIS'    => ($at_page == 2 && $start_page > 2) || ($at_page == $total_pages - 1 && $end_page < $total_pages - 1),
207                  ));
208   
209                  // We may need to jump around in the list depending on whether we have or need to display
210                  // the ellipsis. Are we on page 2 and are we more than one page away from the start
211                  // of the list? Yes? Then we jump to the start of the list. Likewise are we at the end of
212                  // the list and are there more than two pages left in total? Yes? Then jump to the penultimate
213                  // page (so we can display the ellipsis next pass). Else, increment the counter and keep
214                  // going
215                  if ($at_page == 2 && $at_page < $start_page - 1)
216                  {
217                      $at_page = $start_page;
218                  }
219                  else if ($at_page == $end_page && $end_page < $total_pages - 1)
220                  {
221                      $at_page = $total_pages - 1;
222                  }
223                  else
224                  {
225                      $at_page++;
226                  }
227              }
228              while ($at_page <= $total_pages);
229   
230              if ($on_page != $total_pages)
231              {
232                  $u_next_page = $this->generate_page_link($base_url, $on_page + 1, $start_name, $per_page);
233   
234                  $this->template->assign_block_vars($block_var_name, array(
235                      'PAGE_NUMBER'    => '',
236                      'PAGE_URL'        => $u_next_page,
237                      'S_IS_CURRENT'    => false,
238                      'S_IS_PREV'        => false,
239                      'S_IS_NEXT'        => true,
240                      'S_IS_ELLIPSIS'    => false,
241                  ));
242              }
243          }
244   
245          // If the block_var_name is a nested block, we will use the last (most
246          // inner) block as a prefix for the template variables. If the last block
247          // name is pagination, the prefix is empty. If the rest of the
248          // block_var_name is not empty, we will modify the last row of that block
249          // and add our pagination items.
250          $tpl_block_name = $tpl_prefix = '';
251          if (strrpos($block_var_name, '.') !== false)
252          {
253              $tpl_block_name = substr($block_var_name, 0, strrpos($block_var_name, '.'));
254              $tpl_prefix = strtoupper(substr($block_var_name, strrpos($block_var_name, '.') + 1));
255          }
256          else
257          {
258              $tpl_prefix = strtoupper($block_var_name);
259          }
260          $tpl_prefix = ($tpl_prefix == 'PAGINATION') ? '' : $tpl_prefix . '_';
261   
262          $template_array = array(
263              $tpl_prefix . 'BASE_URL'        => is_string($base_url) ? $base_url : '',//@todo: Fix this for routes
264              $tpl_prefix . 'START_NAME'        => $start_name,
265              $tpl_prefix . 'PER_PAGE'        => $per_page,
266              'U_' . $tpl_prefix . 'PREVIOUS_PAGE'    => ($on_page != 1) ? $u_previous_page : '',
267              'U_' . $tpl_prefix . 'NEXT_PAGE'        => ($on_page != $total_pages) ? $u_next_page : '',
268              $tpl_prefix . 'TOTAL_PAGES'        => $total_pages,
269              $tpl_prefix . 'CURRENT_PAGE'    => $on_page,
270              $tpl_prefix . 'PAGE_NUMBER'        => $this->on_page($num_items, $per_page, $start),
271          );
272   
273          if ($tpl_block_name)
274          {
275              $this->template->alter_block_array($tpl_block_name, $template_array, true, 'change');
276          }
277          else
278          {
279              $this->template->assign_vars($template_array);
280          }
281      }
282   
283      /**
284      * Get current page number
285      *
286      * @param int $per_page the number of items, posts, etc. per page
287      * @param int $start the item which should be considered currently active, used to determine the page we're on
288      * @return int    Current page number
289      */
290      public function get_on_page($per_page, $start)
291      {
292          return floor((int) $start / (int) $per_page) + 1;
293      }
294   
295      /**
296      * Return current page
297      *
298      * @param int $num_items the total number of items, posts, topics, etc.
299      * @param int $per_page the number of items, posts, etc. per page
300      * @param int $start the item which should be considered currently active, used to determine the page we're on
301      * @return string Descriptive pagination string (e.g. "page 1 of 10")
302      */
303      public function on_page($num_items, $per_page, $start)
304      {
305          $on_page = $this->get_on_page($per_page, $start);
306          return $this->user->lang('PAGE_OF', $on_page, max(ceil($num_items / $per_page), 1));
307      }
308   
309      /**
310      * Get current page number
311      *
312      * @param int $start the item which should be considered currently active, used to determine the page we're on
313      * @param int $per_page the number of items, posts, etc. per page
314      * @param int $num_items the total number of items, posts, topics, etc.
315      * @return int    Current page number
316      */
317      public function validate_start($start, $per_page, $num_items)
318      {
319          if ($start < 0 || $start >= $num_items)
320          {
321              return ($start < 0 || $num_items <= 0) ? 0 : floor(($num_items - 1) / $per_page) * $per_page;
322          }
323   
324          return $start;
325      }
326   
327      /**
328      * Get new start when searching from the end
329      *
330      * If the user is trying to reach late pages, start searching from the end.
331      *
332      * @param int $start the item which should be considered currently active, used to determine the page we're on
333      * @param int $limit the number of items, posts, etc. to display
334      * @param int $num_items the total number of items, posts, topics, etc.
335      * @return int    Current page number
336      */
337      public function reverse_start($start, $limit, $num_items)
338      {
339          return max(0, $num_items - $limit - $start);
340      }
341   
342      /**
343      * Get new item limit when searching from the end
344      *
345      * If the user is trying to reach late pages, start searching from the end.
346      * In this case the items to display might be lower then the actual per_page setting.
347      *
348      * @param int $start the item which should be considered currently active, used to determine the page we're on
349      * @param int $per_page the number of items, posts, etc. per page
350      * @param int $num_items the total number of items, posts, topics, etc.
351      * @return int    Current page number
352      */
353      public function reverse_limit($start, $per_page, $num_items)
354      {
355          if ($start + $per_page > $num_items)
356          {
357              return min($per_page, max(1, $num_items - $start));
358          }
359   
360          return $per_page;
361      }
362  }
363