-
Notifications
You must be signed in to change notification settings - Fork 0
/
readmore.module
133 lines (112 loc) · 3.68 KB
/
readmore.module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
/**
* @file
* Basic functional for readmore module.
*/
define('READMORE_MODULE_PATH', drupal_get_path('module', 'readmore'));
include_once DRUPAL_ROOT . '/' . READMORE_MODULE_PATH . '/readmore.field.inc';
/**
* Implements hook_theme().
*/
function readmore_theme() {
$base = array(
'path' => READMORE_MODULE_PATH . '/theme',
);
return array(
'readmore' => array(
'variables' => array(
'summary' => NULL,
'other' => NULL,
'ellips' => NULL,
),
'template' => 'readmore',
) + $base,
);
}
/**
* Truncate string by a number of characters.
*
* @param string $text
* The string to truncate.
* @param string $format
* The format of the content.
* @param int $size
* An upper limit on the returned string length.
* @param bool $wordsafe
* If TRUE, attempt to truncate on a word boundary.
*
* @return string
* Return truncated string.
*/
function readmore_truncate_string($text, $format = NULL, $size = NULL, $wordsafe = FALSE, $use_break = TRUE) {
if (!isset($size)) {
// If size is not set then use default.
$size = 500;
}
if ($use_break) {
// Find where the delimiter is in the body.
$delimiter = strpos($text, '<!--break-->');
if ($delimiter) {
// Set new size.
$size = $delimiter;
}
}
// We check for the presence of the PHP evaluator filter in the current
// format. If the body contains PHP code just return as is.
if (isset($format)) {
$filters = filter_list_format($format);
if (isset($filters['php_code']) && $filters['php_code']->status && strpos($text, '<?') !== FALSE) {
return $text;
}
}
// The summary may not be longer than maximum length specified. Initial slice.
$summary = truncate_utf8($text, $size, $wordsafe, FALSE);
if ($wordsafe) {
// Store the actual length of the truncated string.
$max_rpos = drupal_strlen($summary);
// How much to cut off the end of the summary so that it doesn't end in the
// middle of a paragraph, sentence, or word.
// Initialize it to maximum in order to find the minimum.
$min_rpos = $max_rpos;
// Store the reverse of the summary.
$reversed = strrev($summary);
// Build an array of arrays of break points grouped by preference.
$break_points = array();
// A paragraph near the end of sliced summary is most preferable.
$break_points[] = array('</p>' => 0);
// If no complete paragraph then treat line breaks as paragraphs.
$line_breaks = array('<br />' => 6, '<br>' => 4);
// Newline only indicates a line break if line break converter
// filter is present.
if (isset($filters['filter_autop'])) {
$line_breaks["\n"] = 1;
}
$break_points[] = $line_breaks;
// If the first paragraph is too long, split at the end of a sentence.
$break_points[] = array(
'. ' => 1,
'! ' => 1,
'? ' => 1,
'。' => 0,
'؟ ' => 1,
);
// Iterate over the groups of break points until a break point is found.
foreach ($break_points as $points) {
// Look for each break point, starting at the end of the summary.
foreach ($points as $point => $offset) {
// The summary is already reversed, but the break point isn't.
$rpos = strpos($reversed, strrev($point));
if ($rpos !== FALSE) {
$min_rpos = min($rpos + $offset, $min_rpos);
}
}
// If a break point was found in this group, slice and stop searching.
if ($min_rpos !== $max_rpos) {
// Don't slice with length 0. Length must be <0 to slice from RHS.
$summary = ($min_rpos === 0) ? $summary : drupal_substr($summary, 0, 0 - $min_rpos);
break;
}
}
}
return $summary;
}