function smart_trim_field_formatter_view in Smart Trim 7
Implements hook_field_formatter_view().
Need a better way to handle doing count by words instead of characters (see views_trim_text().
File
- ./
smart_trim.module, line 40 - Module functionality.
Code
function smart_trim_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
$settings = $display['settings'];
switch ($display['type']) {
case 'smart_trim_format':
foreach ($items as $delta => $item) {
// The default behaviour is to use the main body field, but the summary
// option allows users to use the summary field IFF it is not empty.
$break_pos = strpos($item['value'], '<!--break-->');
$has_summary_or_break = !empty($item['summary']) || $break_pos !== FALSE;
$honor_trim = empty($settings['summary_handler']) || $settings['summary_handler'] != 'full' ? TRUE : FALSE;
if (!empty($settings['summary_handler']) && $settings['summary_handler'] != 'ignore' && $has_summary_or_break) {
if (empty($item['summary'])) {
$output = check_markup(substr($item['value'], 0, $break_pos), $item['format'], $langcode, FALSE);
}
else {
$output = _text_sanitize($instance, $langcode, $item, 'summary');
}
}
else {
$output = _text_sanitize($instance, $langcode, $item, 'value');
}
// Process additional options (currently only HTML on/off).
if (!empty($settings['trim_options'])) {
if (!empty($settings['trim_options']['text'])) {
// Strip tags.
$preserve_tags = !empty($settings['trim_preserve_tags']) ? $settings['trim_preserve_tags'] : '';
$output = strip_tags(str_replace('<', ' <', $output), $preserve_tags);
// Strip out line breaks.
$output = preg_replace('/\\n|\\r|\\t/m', ' ', $output);
// Strip out non-breaking spaces.
$output = str_replace(' ', ' ', $output);
$output = str_replace(" ", ' ', $output);
// Strip out extra spaces.
$output = trim(preg_replace('/\\s\\s+/', ' ', $output));
}
}
// Make the trim, provided we're honoring trim settings
// or there's no summary or break available.
$shortened = FALSE;
if ($honor_trim || $has_summary_or_break === FALSE) {
if ($settings['trim_type'] == 'words') {
// Only bother with this is we have to.
if ($settings['trim_length'] < str_word_count($output)) {
// Use \s or use PREG_CLASS_UNICODE_WORD_BOUNDARY?
$words = preg_split('/\\s/', $output, NULL, PREG_SPLIT_NO_EMPTY);
$output2 = implode(" ", array_slice($words, 0, $settings['trim_length']));
$output2 = _filter_htmlcorrector($output2);
}
else {
$output2 = $output;
}
}
else {
// Use views_trim_text() if available.
if (module_exists('views')) {
$output2 = views_trim_text(array(
'max_length' => $settings['trim_length'],
'word_boundary' => TRUE,
'ellipsis' => FALSE,
'html' => TRUE,
), $output);
}
else {
// @see http://api.drupal.org/api/drupal/modules%21field%21modules%21text%21text.module/function/text_summary/7
// text_summary is smart about looking for paragraphs, sentences,
// etc, not strictly just length. Uses truncate_utf8 as well.
$output2 = text_summary($output, $instance['settings']['text_processing'] ? $item['format'] : NULL, $settings['trim_length']);
}
}
// Verify if we actually performed any shortening.
if (drupal_strlen(drupal_html_to_text($output)) != drupal_strlen(drupal_html_to_text($output2))) {
$shortened = TRUE;
}
$output = $output2;
}
// Only include the extension if the text was truncated.
$extension = '';
if ($shortened) {
$extension = filter_xss($settings['trim_suffix']);
}
// Don't duplicate period at end of text and beginning of extension.
if (substr($output, -1, 1) == '.' && substr($extension, 0, 1) == '.') {
$extension = substr($extension, 1);
}
// Final checks if we need to display a more link.
$needs_more = FALSE;
switch ($settings['more_link']) {
// If the user always wants the link, include it.
case SMART_TRIM_ALWAYS:
$needs_more = TRUE;
break;
case SMART_TRIM_IFNEEDED:
if ($shortened) {
$needs_more = TRUE;
}
else {
// If a summary is used (whether truncated or not), and it's
// different from the main body, we need to show the more link.
if (!empty($item['summary']) && $settings['summary_handler'] != 'ignore') {
$summary_output = _text_sanitize($instance, $langcode, $item, 'summary');
$full_output = _text_sanitize($instance, $langcode, $item, 'value');
if (strcmp($summary_output, $full_output) != 0) {
$needs_more = TRUE;
}
}
}
break;
}
$uri = entity_uri($entity_type, $entity);
if ($uri && $needs_more) {
$extension .= l(t('@more_text', array(
'@more_text' => $settings['more_text'],
)), $uri['path'], array(
'html' => TRUE,
'attributes' => array(
'class' => array(
'more-link',
),
),
));
}
$output_appended = preg_replace('#^(.*)(\\s?)(</[^>]+>)$#Us', '$1' . $extension . '$3', $output);
// Check if the regex did anything. if not, append manually.
if ($output_appended == $output) {
$output_appended = $output . $extension;
}
// If linking to content is selected the trimmed text will have tags
// removed from the trimmed text. Need to find a more elegant way of
// doing this without conflicting the other settings.
if (!empty($settings['trim_link']) && !empty($uri['path'])) {
$output_appended = strip_tags($output_appended);
$output = l($output_appended, $uri['path']);
$element[$delta] = array(
'#markup' => $output,
);
return $element;
}
$element[$delta] = array(
'#markup' => $output_appended,
);
}
break;
}
return $element;
}