Ok, so I have this function that truncates a string but is good not to cut off HTML Tags or cut off halfway through a word (except it has a problem). However, if you'll notice with the first string, it cuts off the front of the string for some reason. I don't know why it does this. Can anyone help me figure it out and fix it? Thanks so much in advance!
I'm not sure what the problem is, but this is what is supposed to happen. The function reads through the string and puts open tags in an array. It removes them from the array upon closing. It truncates at $length unless $length is in the middle of a word. In that case it will move to the end of that word and truncate there.
Below is the script, and here is the output
http://caseybritt.com/safesubstr/
<?php
function safe_substr($string, $length)
{
if( !empty( $string ) && $length>0 ) {
$isText = true;
$ret = "";
$i = 0;
$currentChar = "";
$lastSpacePosition = -1;
$lastChar = "";
$tagsArray = array();
$currentTag = "";
$tagLevel = 0;
$noTagLength = strlen( strip_tags( $string ) );
// Parser loop
for( $j=0; $j<strlen( $string ); $j++ ) {
$currentChar = substr( $string, $j, 1 );
$ret .= $currentChar;
// Lesser than event
if( $currentChar == "<") $isText = false;
// Character handler
if( $isText ) {
// Memorize last space position
if( $currentChar == " " ) { $lastSpacePosition = $j; }
else { $lastChar = $currentChar; }
$i++;
} else {
$currentTag .= $currentChar;
}
// Greater than event
if( $currentChar == ">" ) {
$isText = true;
// Opening tag handler
if( ( strpos( $currentTag, "<" ) !== FALSE ) &&
( strpos( $currentTag, "/>" ) === FALSE ) &&
( strpos( $currentTag, "</") === FALSE ) ) {
// Tag has attribute(s)
if( strpos( $currentTag, " " ) !== FALSE ) {
$currentTag = substr( $currentTag, 1, strpos( $currentTag, " " ) - 1 );
} else {
// Tag doesn't have attribute(s)
$currentTag = substr( $currentTag, 1, -1 );
}
array_push( $tagsArray, $currentTag );
} else if( strpos( $currentTag, "</" ) !== FALSE ) {
array_pop( $tagsArray );
}
$currentTag = "";
}
if( $i >= $length) {
break;
}
}
// Cut HTML string at last space position
if( $length < $noTagLength ) {
if( $lastSpacePosition != -1 ) {
$ret = substr( $string, 0, $lastSpacePosition );
} else {
$ret = substr( $string, $j );
}
}
// Close broken XHTML elements
while( sizeof( $tagsArray ) != 0 ) {
$aTag = array_pop( $tagsArray );
$ret .= "</" . $aTag . ">";
}
} else {
$ret = "";
}
return( $ret );
}
$string = '<strong>bold</strong><br />
<em>italic</em><br />
<del>strikethrough</del><br />
NORMAL<sup>superscript</sup>normal<br />
<span style="color: #ff0000">colored</span><br />
<a href="http://aol.com">aol.com</a><br />
<a href="http://aol.com">OH YEA</a><br />
<a href="http://aol.com" target="_blank">aol.com</a><br />
<a href="http://aol.com" target="_blank">OH YEA</a>';
$string2 = '<a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>,
<a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>, <a href="http://aol.com">dance</a>';
echo safe_substr($string, 50);
echo safe_substr($string2, 50);
?>