I have a search result that strictly counts the number of characters before and after the SEARCH TERM when cutting off the full string. Unfortunately, this causes the output to cut off words in the middle. (...with an ellipse before and after the counting)
I am trying to have the search result cut off the full string ONLY at white space vs. in the middle of a word.
Here is the function:
private function _highlight_results(){
$GLOBALS['_SEARCH_SUMMARY_LENGTH'] = 24;
foreach($this->results as $url => &$this_result){
if(!$this_result['url_display'] && $this_result['url']){
$this_result['url_display'] = $this_result['url'];
}
foreach($this_result['search_term'] as $search_term){
$search_term = preg_quote($search_term,'/');
foreach(array('title','summary','url_display') as $highlight_item){
if($this_result[$highlight_item] && preg_match('/'.$search_term.'/i',$this_result[$highlight_item])){
if($highlight_item != 'url_display' && strlen($this_result[$highlight_item]) > $GLOBALS['_SEARCH_SUMMARY_LENGTH']){
$boobs = ceil(($GLOBALS['_SEARCH_SUMMARY_LENGTH']-strlen($this->_search_term))/2);
preg_match('/(.{0,'.$boobs.'})('.$search_term.')(.{0,'.$boobs.'})/i',$this_result[$highlight_item],$matches);
// want to even out the strings a bit so if highlighted term is at end of string, put more characters infront.
$before_limit = $after_limit = ($boobs - 2);
if(strlen($matches[1])>=$before_limit && strlen($matches[3])>=$after_limit){
// leave limit alone.
}else if(strlen($matches[1])<$before_limit){
$after_limit += $before_limit - strlen($matches[1]);
$before_limit = strlen($matches[1]);
preg_match('/(.{0,'.($before_limit+2).'})('.$search_term.')(.{0,'.($after_limit+2).'})/i',$this_result[$highlight_item],$matches);
}else if(strlen($matches[3])<$after_limit){
$before_limit += $after_limit - strlen($matches[3]);
$after_limit = strlen($matches[3]);
preg_match('/(.{0,'.($before_limit+2).'})('.$search_term.')(.{0,'.($after_limit+2).'})/i',$this_result[$highlight_item],$matches);
}
$this_result[$highlight_item] = (strlen($matches[1])>$before_limit) ? '...'.substr($matches[1],-$before_limit) : $matches[1];
$this_result[$highlight_item] .= $matches[2];
$this_result[$highlight_item] .= (strlen($matches[3])>$after_limit) ? substr($matches[3],0,$after_limit).'...' : $matches[3];
}
}else if(strlen($this_result[$highlight_item]) > $GLOBALS['_SEARCH_SUMMARY_LENGTH']){
$this_result[$highlight_item] = substr($this_result[$highlight_item],0,$GLOBALS['_SEARCH_SUMMARY_LENGTH']).'...';
}
}
}
foreach($this_result['search_term'] as $search_term){
$search_term = preg_quote($search_term,'/');
foreach(array('title','summary','url_display') as $highlight_item){
$this_result[$highlight_item] = preg_replace('/'.$search_term.'/i','<span id="phpsearch_resultHighlight">$0</span>',$this_result[$highlight_item]);
}
}
}
}
Here's what I was thinking... Just before displaying the string output, the script should loop through the string using a function that 'looks for' an ellipse and an immediate character and then removes the character AFTER and continues looping until a white space is found. Then, the next loop would 'look for' a character and then an ellipse and then removes the character and continues looping until a white space is found BEFORE the ellipse.
Here's some very sad pseudo code of my description above:
WHILE (not the end of the string) {
// NOT SURE IF I NEED A FOREACH LOOP HERE TO CHECK EACH CHAR
IF ( ^ ('...' and an immediate char are found) ) {
delete chars until a white space is found;
// if '...' is deleted along with the chars, then put the '...' back in:
//string .= '...' . string;
}
IF ( $ (a char and an immediate '...' are found) ) {
delete chars until a white space is found;
// if '...' is deleted along with the chars, then put the '...' back in:
//string .= string . '...';
}
}
PRINT string;
I think you can get the idea of what I'm looking for from the stuff above. I have researched and tested wordwrap() but still have not found THE answer.