| 1 |
<?php |
<?php |
| 2 |
// $Id: paging.module,v 1.41 2009/01/25 17:13:56 Gurpartap Exp $ |
// $Id: paging.module,v 1.42 2009/01/26 16:31:46 Gurpartap Exp $ |
| 3 |
// Original module written by Marco Scutari. |
// Original module written by Marco Scutari. |
| 4 |
// Rewritten and considerably shortened and made more Drupal-friendly by Earl Miles. |
// Rewritten and considerably shortened and made more Drupal-friendly by Earl Miles. |
| 5 |
// Yet again rewritten, extended and currently maintained by Gurpartap Singh. |
// Yet again rewritten, extended and currently maintained by Gurpartap Singh. |
| 463 |
$breaks = (int)($total_chars / $max_chars); |
$breaks = (int)($total_chars / $max_chars); |
| 464 |
$bodypart = array(); |
$bodypart = array(); |
| 465 |
for ($i = 0; $i <= $breaks; $i++) { |
for ($i = 0; $i <= $breaks; $i++) { |
| 466 |
$bodypart[$i] = node_teaser($body, NULL, $max_chars); |
$bodypart[$i] = _paging_body_shift($body, $max_chars); |
| 467 |
$bodycount = strlen($bodypart[$i]); |
$bodycount = strlen($bodypart[$i]); |
| 468 |
$body = substr($body, $bodycount); |
$body = substr($body, $bodycount); |
| 469 |
} |
} |
| 644 |
} |
} |
| 645 |
|
|
| 646 |
/** |
/** |
| 647 |
|
* Helper function for automatic page separation by character limit. |
| 648 |
|
*/ |
| 649 |
|
function _paging_body_shift($body, $size) { |
| 650 |
|
// If we have a short body, the entire body is the teaser. |
| 651 |
|
if (drupal_strlen($body) <= $size) { |
| 652 |
|
return $body; |
| 653 |
|
} |
| 654 |
|
|
| 655 |
|
// If the delimiter has not been specified, try to split at paragraph or |
| 656 |
|
// sentence boundaries. |
| 657 |
|
|
| 658 |
|
// The teaser may not be longer than maximum length specified. Initial slice. |
| 659 |
|
$teaser = truncate_utf8($body, $size); |
| 660 |
|
|
| 661 |
|
// Store the actual length of the UTF8 string -- which might not be the same |
| 662 |
|
// as $size. |
| 663 |
|
$max_rpos = strlen($teaser); |
| 664 |
|
|
| 665 |
|
// How much to cut off the end of the teaser so that it doesn't end in the |
| 666 |
|
// middle of a paragraph, sentence, or word. |
| 667 |
|
// Initialize it to maximum in order to find the minimum. |
| 668 |
|
$min_rpos = $max_rpos; |
| 669 |
|
|
| 670 |
|
// Store the reverse of the teaser. We use strpos on the reversed needle and |
| 671 |
|
// haystack for speed and convenience. |
| 672 |
|
$reversed = strrev($teaser); |
| 673 |
|
|
| 674 |
|
// Build an array of arrays of break points grouped by preference. |
| 675 |
|
$break_points = array(); |
| 676 |
|
|
| 677 |
|
// A paragraph near the end of sliced teaser is most preferable. |
| 678 |
|
$break_points[] = array('</p>' => 0); |
| 679 |
|
|
| 680 |
|
// If no complete paragraph then treat line breaks as paragraphs. |
| 681 |
|
$line_breaks = array('<br />' => 6, '<br>' => 4); |
| 682 |
|
// Newline only indicates a line break if line break converter |
| 683 |
|
// filter is present. |
| 684 |
|
if (isset($filters['filter/1'])) { |
| 685 |
|
$line_breaks["\n"] = 1; |
| 686 |
|
} |
| 687 |
|
$break_points[] = $line_breaks; |
| 688 |
|
|
| 689 |
|
// If the first paragraph is too long, split at the end of a sentence. |
| 690 |
|
$break_points[] = array('. ' => 1, '! ' => 1, '? ' => 1, '。' => 0, '؟ ' => 1); |
| 691 |
|
|
| 692 |
|
// Iterate over the groups of break points until a break point is found. |
| 693 |
|
foreach ($break_points as $points) { |
| 694 |
|
// Look for each break point, starting at the end of the teaser. |
| 695 |
|
foreach ($points as $point => $offset) { |
| 696 |
|
// The teaser is already reversed, but the break point isn't. |
| 697 |
|
$rpos = strpos($reversed, strrev($point)); |
| 698 |
|
if ($rpos !== FALSE) { |
| 699 |
|
$min_rpos = min($rpos + $offset, $min_rpos); |
| 700 |
|
} |
| 701 |
|
} |
| 702 |
|
|
| 703 |
|
// If a break point was found in this group, slice and return the teaser. |
| 704 |
|
if ($min_rpos !== $max_rpos) { |
| 705 |
|
// Don't slice with length 0. Length must be <0 to slice from RHS. |
| 706 |
|
return ($min_rpos === 0) ? $teaser : substr($teaser, 0, 0 - $min_rpos); |
| 707 |
|
} |
| 708 |
|
} |
| 709 |
|
|
| 710 |
|
// If a break point was not found, still return a teaser. |
| 711 |
|
return $teaser; |
| 712 |
|
} |
| 713 |
|
|
| 714 |
|
/** |
| 715 |
* Implementation of hook_content_extra_fields(). |
* Implementation of hook_content_extra_fields(). |
| 716 |
* |
* |
| 717 |
* CCK hook to allow sorting of the pager field. |
* CCK hook to allow sorting of the pager field. |