function readmore_truncate_string in Readmore 2.x
Same name and namespace in other branches
- 8 readmore.module \readmore_truncate_string()
- 7 readmore.module \readmore_truncate_string()
Truncate string by a number of characters.
Parameters
string $text: The string to truncate.
string $format: The format of the content.
int $size: An upper limit on the returned string length.
bool $wordsafe: If TRUE, attempt to truncate on a word boundary.
Return value
string Return truncated string.
1 call to readmore_truncate_string()
- ReadmoreFormatter::viewElements in src/
Plugin/ Field/ FieldFormatter/ ReadmoreFormatter.php - Builds a renderable array for a field value.
File
- ./
readmore.module, line 39 - Contains readmore module.
Code
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 = mb_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.
$filters = [];
if (isset($format)) {
$filter_entities = \Drupal::entityTypeManager()
->getStorage('filter_format')
->loadByProperties([
'status' => TRUE,
]);
foreach ($filter_entities as $filter) {
$filters[] = $filter
->id();
if ($filter
->id() == 'php_code' && strpos($text, '<?') !== FALSE) {
return $text;
}
}
}
// The summary may not be longer than maximum length specified. Initial slice.
$summary = Unicode::truncate($text, $size, $wordsafe, FALSE);
if ($wordsafe) {
// Store the actual length of the truncated string.
$max_rpos = mb_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 = [];
// A paragraph near the end of sliced summary is most preferable.
$break_points[] = [
'</p>' => 0,
];
// If no complete paragraph then treat line breaks as paragraphs.
$line_breaks = [
'<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[] = [
'. ' => 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 = mb_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 : mb_substr($summary, 0, 0 - $min_rpos);
break;
}
}
}
return $summary;
}