You are here

class Pagination in Pagination (Node) 6

Same name and namespace in other branches
  1. 7 includes/Pagination.inc \Pagination

@desc Handles all the pagination logic

Hierarchy

Expanded class hierarchy of Pagination

1 string reference to 'Pagination'
theme_pagination_admin_settings in ./pagination.module
@desc Themes the admin form as a table

File

./pagination.module, line 494
pagination.module @desc Allow for arbitrary nodes to be paginated. administrators can set which nodes they wish to paginate, and the length of content required to split a node into pages. Alternatively, content creators can set manual break points…

View source
class Pagination {

  /*  holds the paginated sections  */
  var $page = [];

  /*  holds the headers for the pages */
  var $headers = [];

  /*  holds the nodes paging style  */
  var $style = null;

  /*  holds the nodes paging value  */
  var $value = null;

  /*  regex to parse manual breaks  */
  var $re_custom = '/(<p>\\s*)?\\[\\s*(pagebreak\\s*\\]|(header\\s*=\\s*([^\\]]*)\\]))(\\s*<\\/p>)?/mi';

  /*  regex to parse <h3> breaks  */
  var $re_tag = '/(<p>\\s*)?<h3>\\s*(.*?)\\s*<\\/h3>(\\s*<\\/p>)?/mi';

  /**
   *  @desc   Static call to return a single instance
   *  @return object  Pagination
   *  @static
   */
  function getInstance() {
    static $pagination = [];
    if (empty($pagination)) {
      $pagination['instance'] =& new Pagination();
    }
    return $pagination['instance'];
  }

  /**
   *  @desc   Paginate text
   *  @param  string  text to paginate
   *  @param  int     size of text to make breaks at
   *  @return void
   *  @public
   */
  function paginate($text, $cutoff) {
    $textsize = strlen($text);
    do {
      $section = $this
        ->parseText($text, $cutoff);
      $this->page[] = $section;
      $textsize = strlen($text);
    } while ($textsize > 0);
  }

  /**
   *  @desc   Get pagination style
   *  @param  string  node type
   *  @return int     pagination style
   *  @public
   */
  function getStyle($type) {
    $this->style = $this
      ->getSettings('style', $type);
    return $this->style;
  }

  /**
   *  @desc   Get pagination value
   *  @param  string  node type
   *  @return int     pagination value
   *  @public
   */
  function getValue($type) {
    $this->value = $this
      ->getSettings('value', $type);
    return $this->value;
  }

  /**
   *  @desc   Get page headers
   *  @param  int     nid
   *  @return array   page headers
   *  @public
   */
  function getHeaders($nid = 0) {
    if (!$nid) {
      return array();
    }
    static $query;
    if (!$query and $this->value > PAGINATION_AUTO) {
      $query = 'SELECT headers FROM {node_pagination} WHERE nid = %d';
      $result = db_query($query, $nid);
      $get = db_fetch_object($result);
      $headers = isset($get->headers) ? unserialize($get->headers) : array();
      foreach ($headers as $key => $header) {

        // Page 1 is always the node title
        $this->headers[$key + 1] = $header;
      }
    }
    return $this->headers;
  }

  /**
   *  @desc   Get page count
   *  @return int     total page count
   *  @public
   */
  function getPageCount() {
    return count($this->page);
  }

  /**
   *  @desc   Get page section
   *  @param  int     current page
   *  @return string  page section
   *  @public
   */
  function getPage($page) {
    $section = isset($this->page[$page]) ? $this->page[$page] : '';
    return $section;
  }

  /**
   *  @desc   Get value of $_GET['page']
   *  @return int     value of $_GET['page']
   *  @public
   */
  function getPageVar() {
    $page = isset($_GET['page']) ? $_GET['page'] : 0;
    if (variable_get('pagination_onebased', 1) == 1) {
      $page = $page > 0 ? --$page : $page;
    }
    return $page;
  }

  /**
   *  @desc   Get a themed pager (Drupal default)
   *  @return string  themed pager
   *  @public
   */
  function getPager() {
    global $pager_page_array, $pager_total;
    $pager_page_array = explode(',', (int) $this
      ->getPageVar());
    $pager_total[0] = $this
      ->getPageCount();
    $pager_page_array[0] = max(0, min((int) $pager_page_array[0], (int) $pager_total[0]));
    $pager = theme('pager', null, 1, 0);

    // Drupal default pager is 0 based, we'll use 1 based for ours
    if (variable_get('pagination_onebased', 1)) {
      $regex = '#(\\?|\\&)page=(\\d+)#e';
      $pager = preg_replace($regex, "'\$1page='.(\$2 + 1)", $pager);
    }
    return $pager;
  }

  /**
   *  @desc   Get a themed Table of Contents
   *  @param  int     nid
   *  @param  boolean flag to ignore h4 title when rendered ToC in a block.
   *  @return string  themed ToC
   *  @public
   */
  function getToc($nid, $ignore_title = FALSE) {
    if (!$nid) {
      return;
    }
    drupal_add_css(drupal_get_path('module', 'pagination') . '/pagination.css');
    $toc = array();
    $headers = $this
      ->getHeaders($nid);
    $headers[0] = menu_get_active_title();
    foreach ($headers as $key => $header) {
      $page = $key + 1;
      $header = str_replace(array(
        '<br />',
        '<br>',
      ), '', $header);
      $options = array(
        'attributes' => array(
          'title' => t('Go to page !page', array(
            '!page' => $page,
          )),
        ),
        'query' => 'page=' . $page,
      );
      $toc[] = array(
        'data' => $this
          ->getPageVar() == $key ? check_plain($header) : l($header, $_GET['q'], $options),
        'class' => $this
          ->getPageVar() == $key ? 'pagination-toc-item current' : 'pagination-toc-item',
      );
    }
    $items = theme('item_list', $toc, null, variable_get('pagination_list_type', 'ul'), array(
      'class' => 'pagination-toc-list',
    ));

    // Avoid problems with special chars displaying, likely not an exhaustive
    // regex.
    $items = preg_replace('#&amp;(\\S{2,7}[^;];)#e', "'&\$1'", $items);
    $toc_title = $ignore_title ? NULL : t('Table of Contents:');
    $toc = theme('pagination_toc', $toc_title, drupal_get_title(), $items);
    return $toc;
  }

  /**
   *  @desc   Private method to get pagination settings by content type
   *  @param  string  pagination setting
   *  @param  string  node type
   *  @return array   pagination settings
   *  @private
   */
  function getSettings($setting, $type) {
    static $pagination = [];
    if (!isset($pagination[$type])) {
      $query = "SELECT paginate, style FROM {pagination} WHERE type = '%s'";
      $result = db_query($query, $type);
      $get = db_fetch_object($result);
      $pagination[$type] = array(
        'style' => isset($get->style) ? $get->style : 0,
        'value' => isset($get->paginate) ? $get->paginate : 0,
      );
    }
    $result = isset($pagination[$type][$setting]) ? $pagination[$type][$setting] : 0;
    return $result;
  }

  /**
   *  @desc   Private method to set headers
   *  @param  string  header
   *  @void
   *  @private
   */
  function setHeader($header) {
    static $first;
    if (!$first and $this->value < PAGINATION_AUTO) {

      // Manual paging should have a default header set for page 1
      $first = true;
      $this->headers[] = t('Page 1');
    }
    $this->headers[] = $header;
  }

  /**
   *  @desc   Handle pagination depending on pagination style
   *  @param  string  text to paginate
   *  @param  int     size of text to make breaks at
   *  @return string  section of text
   *  @private
   */
  function parseText(&$text, $cutoff) {
    $page_count = empty($this->headers) ? count($this->headers) + 1 : count($this->headers);
    $section = '';
    switch ($cutoff) {
      case 1:

        // Manual breaks w/custom headers, for [ header = random ] we expect:
        // 0:  [ header = HEADER TEXT ]
        // 4:  HEADER TEXT
        // for [ pagebreak ] we expect:
        // 0:  [ pagebreak ]
        preg_match($this->re_custom, $text, $matches);
        if (isset($matches[0])) {
          $header = isset($matches[4]) && $matches[4] ? $matches[4] : t('Page !num', array(
            '!num' => $page_count + 1,
          ));
          $this
            ->setHeader($header);
          $section = $this
            ->parseSection($text, $matches, 1, 5);
        }
        else {

          // No matches, send back full text
          $section = $text;
          $text = '';
        }
        break;
      case 2:

        // Manual breaks w/h3 tags, we except:
        // 0:  <h3>HEADER TEXT</h3>
        // 2:  HEADER TEXT
        $tag = 'h' . variable_get('pagination_header', 3);
        if ('h3' !== $tag) {
          $this->re_tag = str_replace('h3', $tag, $this->re_tag);
        }
        preg_match($this->re_tag, $text, $matches);
        if (isset($matches[0])) {
          $header = isset($matches[2]) ? $matches[2] : t('Page !num', array(
            '!num' => $page_count + 1,
          ));
          $this
            ->setHeader($header);
          $section = $this
            ->parseSection($text, $matches, 1, 3);
        }
        else {

          // No matches, send back full text
          $section = $text;
          $text = '';
        }
        break;
      default:

        // Paging by words, we'll use the english approximate 5 chars per word
        // + space.
        $header = t('Page !num', array(
          '!num' => $page_count + 1,
        ));
        $this
          ->setHeader($header);
        $section = $this
          ->parseChunk($text, $cutoff * 6);
        $text = substr($text, strlen($section));
        break;
    }
    return $section;
  }

  /**
   *  @desc   Handle splitting of sections in odd edge cases
   *  @param  string  text to parse
   *  @param  array   matches
   *  @param  int     start tag position
   *  @param  int     end tag position
   *  @private
   */
  function parseSection(&$text, $matches, $start, $end) {
    $open = isset($matches[$start]) && !isset($matches[$end]) ? $matches[$start] : '';
    $close = isset($matches[$end]) && $matches[$end] && isset($matches[$start]) && !$matches[$start] ? $matches[$end] : '';
    $split = strpos($text, $matches[0]);
    $section = substr($text, 0, $split) . $close;
    $text = $open . substr($text, $split + strlen($matches[0]));
    return $section;
  }

  /**
   *  @desc   Handle words per page chunking
   *  @param  string  text to parse
   *  @param  int     "maximum" length
   *  @return string  text chunk
   *  @private
   */
  function parseChunk($text, $size) {
    return node_teaser($text, null, $size);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
Pagination::$headers property
Pagination::$page property
Pagination::$re_custom property
Pagination::$re_tag property
Pagination::$style property
Pagination::$value property
Pagination::getHeaders function @desc Get page headers
Pagination::getInstance function @desc Static call to return a single instance
Pagination::getPage function @desc Get page section
Pagination::getPageCount function @desc Get page count
Pagination::getPager function @desc Get a themed pager (Drupal default)
Pagination::getPageVar function @desc Get value of $_GET['page']
Pagination::getSettings function @desc Private method to get pagination settings by content type
Pagination::getStyle function @desc Get pagination style
Pagination::getToc function @desc Get a themed Table of Contents
Pagination::getValue function @desc Get pagination value
Pagination::paginate function @desc Paginate text
Pagination::parseChunk function @desc Handle words per page chunking
Pagination::parseSection function @desc Handle splitting of sections in odd edge cases
Pagination::parseText function @desc Handle pagination depending on pagination style
Pagination::setHeader function @desc Private method to set headers