View source
<?php
define('PAGING_SEPARATOR', variable_get('paging_separator', '<!--pagebreak-->'));
function paging_help($section) {
switch ($section) {
case 'admin/help#paging':
return t('<p>Break long pages into smaller ones by means of a page tag:</p>
<pre>First page here.
%separator
Second page here.
%separator
More pages here.</pre>', array(
'%separator' => PAGING_SEPARATOR,
));
}
}
function paging_menu($maycache) {
if ($maycache) {
$items[] = array(
'path' => 'admin/settings/paging',
'title' => t('Paging'),
'description' => t('Enable or disable paging for certain node types and set other preferences.'),
'callback' => 'drupal_get_form',
'callback arguments' => 'paging_settings',
'access' => user_access('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
);
}
return $items;
}
function paging_settings() {
$form = array();
$form['paging_config'] = array(
'#type' => 'fieldset',
'#title' => t('Basic preferences'),
);
$form['paging_config']['paging_node_types_enabled'] = array(
'#type' => 'checkboxes',
'#title' => t('Node types'),
'#description' => t('Select the node types you want to enable paging for.'),
'#default_value' => variable_get('paging_node_types_enabled', array()),
'#options' => node_get_types('names'),
);
$form['paging_config']['paging_separator'] = array(
'#type' => 'textfield',
'#title' => t('Separator'),
'#size' => 20,
'#maxlength' => 255,
'#default_value' => PAGING_SEPARATOR,
'#required' => TRUE,
'#description' => t('Page separator string. You should use an HTML tag that will render reasonably when paging is not enabled, such as <em><!--pagebreak--></em> or <em><HR /></em>.'),
);
$form['paging_config']['paging_read_more_enabled'] = array(
'#type' => 'checkbox',
'#title' => t('Link "Read more" to the second page'),
'#description' => t('If enabled, the "Read more" link under teasers will link to the 2nd page of the node. Implemented only when the teaser and the first page content is same.'),
'#default_value' => variable_get('paging_read_more_enabled', 0),
);
$form['paging_config']['paging_pager_widget_position'] = array(
'#type' => 'radios',
'#title' => t('Pager position'),
'#options' => array(
'below' => t('Below content'),
'above' => t('Above content'),
'both' => t('Below and above content'),
'manual' => t('None (No output)'),
),
'#required' => TRUE,
'#description' => t('Choose the position of page navigation. If set to %none, <code>@paging</code> can be used to place it at a customizable location.', array(
'%none' => t('None'),
'@paging' => '$node->paging',
)),
'#default_value' => variable_get('paging_pager_widget_position', 'below'),
);
$form['paging_automatic'] = array(
'#type' => 'fieldset',
'#title' => t('Automatic Paging'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#description' => t('Automatic paging is disabled when both methods below are disabled, or when the node already contains the page break separator. Automatic paging by line break is preferred over the method of automatic paging by words.'),
);
$form['paging_automatic']['paging_paragraph'] = array(
'#type' => 'fieldset',
'#title' => t('By line break'),
'#collapsed' => FALSE,
'#prefix' => '<div class="container-inline">',
);
$form['paging_automatic']['paging_paragraph']['paging_automatic_chars'] = array(
'#type' => 'select',
'#title' => t('Length of each page'),
'#options' => array(
0 => t('Disabled'),
500 => t('500 characters'),
750 => t('750 characters'),
1000 => t('1000 characters'),
1500 => t('1500 characters'),
2000 => t('2000 characters'),
2500 => t('2500 characters'),
3000 => t('3000 characters'),
3500 => t('3500 characters'),
4000 => t('4000 characters'),
4500 => t('4500 characters'),
),
'#required' => TRUE,
'#description' => '<br />' . t('Set the number of characters that should be displayed per page. <strong>This is the recommended method</strong> for automatic paging.'),
'#default_value' => variable_get('paging_automatic_chars', 0),
);
$form['paging_automatic']['paging_words'] = array(
'#type' => 'fieldset',
'#title' => t('By words'),
'#collapsed' => FALSE,
);
$form['paging_automatic']['paging_words']['paging_automatic_words'] = array(
'#type' => 'select',
'#title' => t('Length of each page'),
'#options' => array(
0 => t('Disabled'),
100 => t('100 words'),
150 => t('150 words'),
200 => t('200 words'),
250 => t('250 words'),
300 => t('300 words'),
350 => t('350 words'),
400 => t('400 words'),
450 => t('450 words'),
500 => t('500 words'),
550 => t('550 words'),
600 => t('600 words'),
650 => t('650 words'),
700 => t('700 words'),
750 => t('750 words'),
),
'#required' => TRUE,
'#description' => '<br />' . t('Set the number of words that should be displayed per page. This may break your sentences at page breaks.'),
'#default_value' => variable_get('paging_automatic_words', 0),
'#suffix' => '</div>',
);
return system_settings_form($form);
}
function paging_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
if (in_array($node->type, variable_get('paging_node_types_enabled', array()), TRUE)) {
switch ($op) {
case 'load':
case 'view':
case 'alter':
if (isset($node->field_body[0]['view'])) {
_paging_nodeapi($node, $node->field_body[0]['view'], $node->field_teaser[0]['view'], $op, $teaser, $page);
}
elseif (isset($node->field_body[0]['value'])) {
_paging_nodeapi($node, $node->field_body[0]['value'], $node->field_teaser[0]['value'], $op, $teaser, $page);
}
else {
_paging_nodeapi($node, $node->body, $node->teaser, $op, $teaser, $page);
}
break;
}
}
}
function _paging_nodeapi(&$node, &$node_body, &$node_teaser, $op, $teaser, $page) {
switch ($op) {
case 'load':
if (strpos($teaser ? $node_teaser : $node_body, PAGING_SEPARATOR) !== FALSE) {
$pages = explode(PAGING_SEPARATOR, $node_body);
}
else {
$body_parts = $node_body;
if (($max_chars = variable_get('paging_automatic_chars', 0)) != 0) {
$total_chars = strlen($node_body);
$body = $node_body;
if ($total_chars > $max_chars) {
$breaks = (int) ($total_chars / $max_chars);
$bodypart = array();
for ($i = 0; $i <= $breaks; $i++) {
$bodypart[$i] = paging_paragraph_split(trim($body), NULL, $max_chars);
$bodycount = strlen($bodypart[$i]);
$body = substr($body, $bodycount);
}
$body_parts = implode(PAGING_SEPARATOR, $bodypart);
}
}
elseif (($max_words = variable_get('paging_automatic_words', 0)) != 0) {
$words = explode(' ', $node_body);
$total_words = count($words);
if ($total_words > $max_words) {
$breaks = (int) ($total_words / $max_words);
for ($i = 1; $i < $breaks; $i++) {
$index = $i * $max_words;
$words[$index] .= PAGING_SEPARATOR;
}
}
$body_parts = implode(' ', $words);
}
$pages = explode(PAGING_SEPARATOR, $body_parts);
}
foreach ($pages as $key => $page) {
if (is_null($page) || $page == "") {
unset($pages[$key]);
}
}
$node->pages = array_values($pages);
$node->page_count = count($node->pages);
break;
case 'view':
if ($teaser && !$node->in_preview && strpos($node_teaser, '<!--paging_filter-->') !== FALSE) {
if ($node->page_count > 1 && strlen($node->teaser) > strlen($node->pages[0])) {
$node->content['body']['#value'] = check_markup($node->pages[0], $node->format, false);
$node->pagemore = true;
}
}
break;
case 'alter':
if (!$node->in_preview && strpos($teaser ? $node_teaser : $node_body, '<!--paging_filter-->') !== FALSE) {
$element = 1;
$page = isset($_GET['page']) ? $_GET['page'] : '';
$node->teaser = str_replace('<!--paging_filter-->', '', $node_teaser);
if (!$teaser && $node->page_count > 1 && arg(2) != 'print' && arg(2) != 'full' && $page != 'full' && arg(0) != 'book' && arg(1) != 'export') {
global $pager_page_array, $pager_total;
$pager_page_array = explode(',', $page);
$pager_total[$element] = $node->page_count;
$page = isset($pager_page_array[$element]) ? $pager_page_array[$element] : 0;
$node->body = check_markup($node->pages[$page], $node->format, false);
$position = variable_get('paging_pager_widget_position', 'below');
$node->paging = theme('pager', NULL, 1, $element);
if ($position == 'above' || $position == 'both') {
$node->body = $node->paging . $node->body;
}
if ($position == 'below' || $position == 'both') {
$node->body .= $node->paging;
}
$node->body = str_replace('<!--paging_filter-->', '', $node->body);
$node->content['body']['#value'] = $node->body;
}
}
break;
}
}
function paging_paragraph_split($body, $format = NULL, $size = NULL) {
if (!isset($size)) {
$size = variable_get('teaser_length', 600);
}
$delimiter = strpos($body, '<!--break-->');
if ($size == 0 && $delimiter === FALSE) {
return $body;
}
if ($delimiter !== FALSE) {
return substr($body, 0, $delimiter);
}
if (isset($format)) {
$filters = filter_list_format($format);
if (isset($filters['php/0']) && strpos($body, '<?') !== FALSE) {
return $body;
}
}
if (drupal_strlen($body) <= $size) {
return $body;
}
$teaser = truncate_utf8($body, $size);
$max_rpos = strlen($teaser);
$min_rpos = $max_rpos;
$reversed = strrev($teaser);
$break_points = array();
$break_points[] = array(
'</p>' => 0,
);
$line_breaks = array(
'<br />' => 6,
'<br>' => 4,
);
if (isset($filters['filter/1'])) {
$line_breaks["\n"] = 1;
}
$break_points[] = $line_breaks;
$break_points[] = array(
'. ' => 1,
'! ' => 1,
'? ' => 1,
'。' => 0,
'؟ ' => 1,
);
foreach ($break_points as $points) {
foreach ($points as $point => $offset) {
$rpos = strpos($reversed, strrev($point));
if ($rpos !== FALSE) {
$min_rpos = min($rpos + $offset, $min_rpos);
}
}
if ($min_rpos !== $max_rpos) {
return $min_rpos === 0 ? $teaser : substr($teaser, 0, 0 - $min_rpos);
}
}
return $teaser;
}
function paging_link($type, $node = 0, $main = 0) {
$links = array();
if ($type == 'node') {
if (array_key_exists('links', $node)) {
$links = $node->links;
}
if ($main == 1 && $node->teaser && $node->pagemore && variable_get('paging_read_more_enabled', 0)) {
$links['node_read_more'] = array(
'title' => t('Read more'),
'href' => drupal_get_path_alias("node/{$node->nid}"),
'attributes' => array(
'title' => t('Read the rest of this posting.'),
'class' => 'read-more-paging',
),
'query' => 'page=0,1',
);
}
}
return $links;
}
function paging_filter($in_op, $in_delta = 0, $in_format = -1, $in_text = '') {
switch ($in_op) {
case 'list':
return array(
t("Paging"),
);
case 'description':
return t('Allows content to be broken up into pages, using the %separator tag, configurable <a href="!url">here</a>.', array(
'%separator' => PAGING_SEPARATOR,
'!url' => url('admin/settings/paging'),
));
case 'process':
return '<!--paging_filter-->' . $in_text;
default:
return $in_text;
}
}
function paging_filter_tips($in_delta, $in_format, $in_is_long = FALSE) {
if ($in_is_long) {
return '<h1>' . t('Paging Help') . '</h1>' . paging_help('admin/help#paging');
}
else {
return t('Use %separator to create page breaks.', array(
'%separator' => PAGING_SEPARATOR,
));
}
}