[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/phpbb/ -> pagination.php (source)

   1  <?php
   2  /**
   3  *
   4  * This file is part of the phpBB Forum Software package.
   5  *
   6  * @copyright (c) phpBB Limited <https://www.phpbb.com>
   7  * @license GNU General Public License, version 2 (GPL-2.0)
   8  *
   9  * For full copyright and license information, please see
  10  * the docs/CREDITS.txt file.
  11  *
  12  */
  13  
  14  namespace phpbb;
  15  
  16  class pagination
  17  {
  18      /** @var \phpbb\template\template */
  19      protected $template;
  20  
  21      /** @var \phpbb\user */
  22      protected $user;
  23  
  24      /** @var \phpbb\controller\helper */
  25      protected $helper;
  26  
  27      /** @var \phpbb\event\dispatcher_interface */
  28      protected $phpbb_dispatcher;
  29  
  30      /**
  31      * Constructor
  32      *
  33      * @param    \phpbb\template\template            $template
  34      * @param    \phpbb\user                            $user
  35      * @param    \phpbb\controller\helper            $helper
  36      * @param    \phpbb\event\dispatcher_interface    $phpbb_dispatcher
  37      */
  38  	public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\controller\helper $helper, \phpbb\event\dispatcher_interface $phpbb_dispatcher)
  39      {
  40          $this->template = $template;
  41          $this->user = $user;
  42          $this->helper = $helper;
  43          $this->phpbb_dispatcher = $phpbb_dispatcher;
  44      }
  45  
  46      /**
  47      * Generate a pagination link based on the url and the page information
  48      *
  49      * @param string|array $base_url is url prepended to all links generated within the function
  50      *                            If you use page numbers inside your controller route, base_url should contains a placeholder (%d)
  51      *                            for the page. Also be sure to specify the pagination path information into the start_name argument
  52      * @param string $on_page is the page for which we want to generate the link
  53      * @param string $start_name is the name of the parameter containing the first item of the given page (example: start=20)
  54      *                            If you use page numbers inside your controller route, start name should be the string
  55      *                            that should be removed for the first page (example: /page/%d)
  56      * @param int $per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce
  57      * @return string URL for the requested page
  58      */
  59  	protected function generate_page_link($base_url, $on_page, $start_name, $per_page)
  60      {
  61          // A listener can set this variable to the new pagination URL
  62          // to override the generate_page_link() function generated value
  63          $generate_page_link_override = false;
  64  
  65          /**
  66          * Execute code and/or override generate_page_link()
  67          *
  68          * To override the generate_page_link() function generated value
  69          * set $generate_page_link_override to the new URL value
  70          *
  71          * @event core.pagination_generate_page_link
  72          * @var string|array base_url is url prepended to all links generated within the function
  73          *                            If you use page numbers inside your controller route, base_url should contains a placeholder (%d)
  74          *                            for the page. Also be sure to specify the pagination path information into the start_name argument
  75          * @var string on_page is the page for which we want to generate the link
  76          * @var string start_name is the name of the parameter containing the first item of the given page (example: start=20)
  77          *                            If you use page numbers inside your controller route, start name should be the string
  78          *                            that should be removed for the first page (example: /page/%d)
  79          * @var int per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce
  80          * @var bool|string generate_page_link_override Shall we return custom pagination link (string URL) or not (false)
  81          * @since 3.1.0-RC5
  82          */
  83          $vars = array('base_url', 'on_page', 'start_name', 'per_page', 'generate_page_link_override');
  84          extract($this->phpbb_dispatcher->trigger_event('core.pagination_generate_page_link', compact($vars)));
  85  
  86          if ($generate_page_link_override)
  87          {
  88              return $generate_page_link_override;
  89          }
  90  
  91          if (!is_string($base_url))
  92          {
  93              if (is_array($base_url['routes']))
  94              {
  95                  $route = ($on_page > 1) ? $base_url['routes'][1] : $base_url['routes'][0];
  96              }
  97              else
  98              {
  99                  $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  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1