I found this old PHP truncate script that doesn’t seem to work all that well. When it truncates the text, it always ends up destroying the website’s html because it doesn’t close the tags properly. Can someone look at it and tell me where the problem might be? I am not good with understanding PHP, so I hope someone could provide a bit of clarity…
[php]function TruncateText($text, $max_length, $break_with = ’ ', $min_after_break = 1, $padding_element = ‘[ … ]’, $padding_anchor_href = ‘’, $padding_anchor_title = ‘’)
{
if (empty($max_length) || empty($text))
return $text;
if (strlen($text) > $max_length)
{
// we are looking for the first instance of $break_with AT/AFTER the max_length
$breakpoint = strpos($text, $break_with, $max_length);
// there has to be a breakpoint
if (!empty($breakpoint))
{
$after_breakpoint = substr($text, $breakpoint);
// there must be a minimum # of characters after the break point
if (strlen($after_breakpoint) <= $min_after_break)
return $text;
$before_breakpoint = substr($text, 0, $breakpoint);
$last_chars = array();
$last_chars[9] = substr($before_breakpoint, $breakpoint - 9, $breakpoint);
$last_chars[2] = substr($last_chars[9], -2);
$last_chars[3] = substr($last_chars[9], -3);
$last_chars[4] = substr($last_chars[9], -4);
$last_chars[5] = substr($last_chars[9], -5);
$last_chars[6] = substr($last_chars[9], -6);
$last_chars[7] = substr($last_chars[9], -7);
$last_chars[8] = substr($last_chars[9], -8);
// common html tags that need a closing tag
$html_tags = array('a', 'abbr', 'area', 'b', 'center', 'div', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'i', 'label', 'li', 'noscript', 'object', 'p', 'pre', 'script', 'span', 'strike', 'strong', 'sub', 'sup', 'table', 'td', 'th', 'thead', 'tr', 'tt', 'ul', 'u');
// most common self-closing tags
$self_closing_tags = array('br', 'hr', 'img', 'input', 'param', 'span');
// self-closing tags...
foreach ($self_closing_tags as $tag)
{
// make sure the last occurrence of this tag in the text was closed....
$pos = strrpos($before_breakpoint, '<' . $tag);
// chop off the broken self-closing tag....
if ($pos !== false && strpos(substr($before_breakpoint, $pos), '/>') === false)
$before_breakpoint = substr($before_breakpoint, 0, $pos);
}
$closing_tags_needed = array();
foreach ($html_tags as $tag)
{
$num_open = substr_count($before_breakpoint, '<'. $tag . '>');
$num_closed = substr_count($before_breakpoint, '</'. $tag . '>');
if ($num_open > $num_closed)
{
$num_closers_needed = $num_open - $num_closed;
$closing_tags_needed[$tag] = $num_closers_needed;
}
// if the text ends with a broken tag... we'll just cut it off....
$l = strlen($tag) + 1;
if (isset($last_chars[$l]) && $last_chars[$l] == '<' . $tag)
$before_breakpoint = substr($before_breakpoint, (-1) * $l);
}
// add closing tags if needed
if (!empty($closing_tags_needed))
foreach($closing_tags_needed as $tag => $num_needed)
for($i = 0; $i < $num_needed; $i++)
$before_breakpoint = $before_breakpoint . '</'. $tag . '>';
// $min_after_break has to be at least 1 and has to be an int
if (!is_int($min_after_break) || $min_after_break <= 0)
$min_after_break = 1;
// set $text equal to the sub string before the breakpoint
$text = $before_breakpoint;
// do we want to add on a padding element?
if (!empty($padding_element))
{
// will this padding_element be an anchor?
if (!empty($padding_anchor_href))
{
$text = $text . ' <span class="logreg"><a href="'. $padding_anchor_href .'"'. (!empty($padding_anchor_title) ? ' title="'. $padding_anchor_title .'"' : '') .' style="white-space:nowrap; font-weight: bold;" rel="nofollow">'. $padding_element .'</a></span>';
}
else
$text = $text . ' ' . $padding_element;
}
}
}
return $text;
}[/php]