[ Index ]

PHP Cross Reference of phpBB-3.1.10-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 $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 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 $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 null
 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          $total_pages = ceil($num_items / $per_page);
 140          $on_page = $this->get_on_page($per_page, $start);
 141          $u_previous_page = $u_next_page = '';
 142  
 143          if ($total_pages > 1)
 144          {
 145              if ($reverse_count)
 146              {
 147                  $start_page = ($total_pages > 5) ? $total_pages - 4 : 1;
 148                  $end_page = $total_pages;
 149              }
 150              else
 151              {
 152                  // What we're doing here is calculating what the "start" and "end" pages should be. We
 153                  // do this by assuming pagination is "centered" around the currently active page with
 154                  // the three previous and three next page links displayed. Anything more than that and
 155                  // we display the ellipsis, likewise anything less.
 156                  //
 157                  // $start_page is the page at which we start creating the list. When we have five or less
 158                  // pages we start at page 1 since there will be no ellipsis displayed. Anymore than that
 159                  // and we calculate the start based on the active page. This is the min/max calculation.
 160                  // First (max) would we end up starting on a page less than 1? Next (min) would we end
 161                  // up starting so close to the end that we'd not display our minimum number of pages.
 162                  //
 163                  // $end_page is the last page in the list to display. Like $start_page we use a min/max to
 164                  // determine this number. Again at most five pages? Then just display them all. More than
 165                  // five and we first (min) determine whether we'd end up listing more pages than exist.
 166                  // We then (max) ensure we're displaying the minimum number of pages.
 167                  $start_page = ($total_pages > 5) ? min(max(1, $on_page - 2), $total_pages - 4) : 1;
 168                  $end_page = ($total_pages > 5) ? max(min($total_pages, $on_page + 2), 5) : $total_pages;
 169              }
 170  
 171              if ($on_page != 1)
 172              {
 173                  $u_previous_page = $this->generate_page_link($base_url, $on_page - 1, $start_name, $per_page);
 174  
 175                  $this->template->assign_block_vars($block_var_name, array(
 176                      'PAGE_NUMBER'    => '',
 177                      'PAGE_URL'        => $u_previous_page,
 178                      'S_IS_CURRENT'    => false,
 179                      'S_IS_PREV'        => true,
 180                      'S_IS_NEXT'        => false,
 181                      'S_IS_ELLIPSIS'    => false,
 182                  ));
 183              }
 184  
 185              // This do...while exists purely to negate the need for start and end assign_block_vars, i.e.
 186              // to display the first and last page in the list plus any ellipsis. We use this loop to jump
 187              // around a little within the list depending on where we're starting (and ending).
 188              $at_page = 1;
 189              do
 190              {
 191                  // We decide whether to display the ellipsis during the loop. The ellipsis is always
 192                  // displayed as either the second or penultimate item in the list. So are we at either
 193                  // of those points and of course do we even need to display it, i.e. is the list starting
 194                  // on at least page 3 and ending three pages before the final item.
 195                  $this->template->assign_block_vars($block_var_name, array(
 196                      'PAGE_NUMBER'    => $at_page,
 197                      'PAGE_URL'        => $this->generate_page_link($base_url, $at_page, $start_name, $per_page),
 198                      'S_IS_CURRENT'    => (!$ignore_on_page && $at_page == $on_page),
 199                      'S_IS_NEXT'        => false,
 200                      'S_IS_PREV'        => false,
 201                      'S_IS_ELLIPSIS'    => ($at_page == 2 && $start_page > 2) || ($at_page == $total_pages - 1 && $end_page < $total_pages - 1),
 202                  ));
 203  
 204                  // We may need to jump around in the list depending on whether we have or need to display
 205                  // the ellipsis. Are we on page 2 and are we more than one page away from the start
 206                  // of the list? Yes? Then we jump to the start of the list. Likewise are we at the end of
 207                  // the list and are there more than two pages left in total? Yes? Then jump to the penultimate
 208                  // page (so we can display the ellipsis next pass). Else, increment the counter and keep
 209                  // going
 210                  if ($at_page == 2 && $at_page < $start_page - 1)
 211                  {
 212                      $at_page = $start_page;
 213                  }
 214                  else if ($at_page == $end_page && $end_page < $total_pages - 1)
 215                  {
 216                      $at_page = $total_pages - 1;
 217                  }
 218                  else
 219                  {
 220                      $at_page++;
 221                  }
 222              }
 223              while ($at_page <= $total_pages);
 224  
 225              if ($on_page != $total_pages)
 226              {
 227                  $u_next_page = $this->generate_page_link($base_url, $on_page + 1, $start_name, $per_page);
 228  
 229                  $this->template->assign_block_vars($block_var_name, array(
 230                      'PAGE_NUMBER'    => '',
 231                      'PAGE_URL'        => $u_next_page,
 232                      'S_IS_CURRENT'    => false,
 233                      'S_IS_PREV'        => false,
 234                      'S_IS_NEXT'        => true,
 235                      'S_IS_ELLIPSIS'    => false,
 236                  ));
 237              }
 238          }
 239  
 240          // If the block_var_name is a nested block, we will use the last (most
 241          // inner) block as a prefix for the template variables. If the last block
 242          // name is pagination, the prefix is empty. If the rest of the
 243          // block_var_name is not empty, we will modify the last row of that block
 244          // and add our pagination items.
 245          $tpl_block_name = $tpl_prefix = '';
 246          if (strrpos($block_var_name, '.') !== false)
 247          {
 248              $tpl_block_name = substr($block_var_name, 0, strrpos($block_var_name, '.'));
 249              $tpl_prefix = strtoupper(substr($block_var_name, strrpos($block_var_name, '.') + 1));
 250          }
 251          else
 252          {
 253              $tpl_prefix = strtoupper($block_var_name);
 254          }
 255          $tpl_prefix = ($tpl_prefix == 'PAGINATION') ? '' : $tpl_prefix . '_';
 256  
 257          $template_array = array(
 258              $tpl_prefix . 'BASE_URL'        => is_string($base_url) ? $base_url : '',//@todo: Fix this for routes
 259              $tpl_prefix . 'START_NAME'        => $start_name,
 260              $tpl_prefix . 'PER_PAGE'        => $per_page,
 261              'U_' . $tpl_prefix . 'PREVIOUS_PAGE'    => ($on_page != 1) ? $u_previous_page : '',
 262              'U_' . $tpl_prefix . 'NEXT_PAGE'        => ($on_page != $total_pages) ? $u_next_page : '',
 263              $tpl_prefix . 'TOTAL_PAGES'        => $total_pages,
 264              $tpl_prefix . 'CURRENT_PAGE'    => $on_page,
 265              $tpl_prefix . 'PAGE_NUMBER'        => $this->on_page($num_items, $per_page, $start),
 266          );
 267  
 268          if ($tpl_block_name)
 269          {
 270              $this->template->alter_block_array($tpl_block_name, $template_array, true, 'change');
 271          }
 272          else
 273          {
 274              $this->template->assign_vars($template_array);
 275          }
 276      }
 277  
 278      /**
 279      * Get current page number
 280      *
 281      * @param int $per_page the number of items, posts, etc. per page
 282      * @param int $start the item which should be considered currently active, used to determine the page we're on
 283      * @return int    Current page number
 284      */
 285  	public function get_on_page($per_page, $start)
 286      {
 287          return floor($start / $per_page) + 1;
 288      }
 289  
 290      /**
 291      * Return current page
 292      *
 293      * @param int $num_items the total number of items, posts, topics, etc.
 294      * @param int $per_page the number of items, posts, etc. per page
 295      * @param int $start the item which should be considered currently active, used to determine the page we're on
 296      * @return string Descriptive pagination string (e.g. "page 1 of 10")
 297      */
 298  	public function on_page($num_items, $per_page, $start)
 299      {
 300          $on_page = $this->get_on_page($per_page, $start);
 301          return $this->user->lang('PAGE_OF', $on_page, max(ceil($num_items / $per_page), 1));
 302      }
 303  
 304      /**
 305      * Get current page number
 306      *
 307      * @param int $start the item which should be considered currently active, used to determine the page we're on
 308      * @param int $per_page the number of items, posts, etc. per page
 309      * @param int $num_items the total number of items, posts, topics, etc.
 310      * @return int    Current page number
 311      */
 312  	public function validate_start($start, $per_page, $num_items)
 313      {
 314          if ($start < 0 || $start >= $num_items)
 315          {
 316              return ($start < 0 || $num_items <= 0) ? 0 : floor(($num_items - 1) / $per_page) * $per_page;
 317          }
 318  
 319          return $start;
 320      }
 321  
 322      /**
 323      * Get new start when searching from the end
 324      *
 325      * If the user is trying to reach late pages, start searching from the end.
 326      *
 327      * @param int $start the item which should be considered currently active, used to determine the page we're on
 328      * @param int $limit the number of items, posts, etc. to display
 329      * @param int $num_items the total number of items, posts, topics, etc.
 330      * @return int    Current page number
 331      */
 332  	public function reverse_start($start, $limit, $num_items)
 333      {
 334          return max(0, $num_items - $limit - $start);
 335      }
 336  
 337      /**
 338      * Get new item limit when searching from the end
 339      *
 340      * If the user is trying to reach late pages, start searching from the end.
 341      * In this case the items to display might be lower then the actual per_page setting.
 342      *
 343      * @param int $start the item which should be considered currently active, used to determine the page we're on
 344      * @param int $per_page the number of items, posts, etc. per page
 345      * @param int $num_items the total number of items, posts, topics, etc.
 346      * @return int    Current page number
 347      */
 348  	public function reverse_limit($start, $per_page, $num_items)
 349      {
 350          if ($start + $per_page > $num_items)
 351          {
 352              return min($per_page, max(1, $num_items - $start));
 353          }
 354  
 355          return $per_page;
 356      }
 357  }


Generated: Sun Feb 19 19:52:41 2017 Cross-referenced by PHPXref 0.7.1