diff --git a/e107_handlers/e_parse_class.php b/e107_handlers/e_parse_class.php index b9ea2e9cc..a6e5dd7f1 100644 --- a/e107_handlers/e_parse_class.php +++ b/e107_handlers/e_parse_class.php @@ -9,9 +9,9 @@ * Text processing and parsing functions * * $Source: /cvs_backup/e107_0.8/e107_handlers/e_parse_class.php,v $ -* $Revision: 1.89 $ -* $Date: 2010-01-02 21:42:51 $ -* $Author: e107steved $ +* $Revision: 1.90 $ +* $Date: 2010-01-09 13:17:45 $ +* $Author: secretr $ * */ if (!defined('e107_INIT')) { exit(); } @@ -771,6 +771,109 @@ class e_parse // Return contents of the drain return $drain; } + + /** + * CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org) + * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org) + * + * Truncate a HTML string + * + * Cuts a string to the length of $length and adds the value of $ending if the text is longer than length. + * + * @param string $text String to truncate. + * @param integer $length Length of returned string, including ellipsis. + * @param string $ending It will be used as Ending and appended to the trimmed string. + * @param boolean $exact If false, $text will not be cut mid-word + * @return string Trimmed string. + */ + function html_truncate($text, $length = 100, $ending = '...', $exact = true) + { + if($this->uStrLen(preg_replace('/<.*?>/', '', $text)) <= $length) + { + return $text; + } + $totalLength = 0; + $openTags = array(); + $truncate = ''; + preg_match_all('/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER); + foreach($tags as $tag) + { + if(!preg_match('/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/si', $tag[2])) + { + if(preg_match('/<[\w]+[^>]*>/s', $tag[0])) + { + array_unshift($openTags, $tag[2]); + } + else if(preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag)) + { + $pos = array_search($closeTag[1], $openTags); + if($pos !== false) + { + array_splice($openTags, $pos, 1); + } + } + } + $truncate .= $tag[1]; + $contentLength = $this->uStrLen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3])); + if($contentLength + $totalLength > $length) + { + $left = $length - $totalLength; + $entitiesLength = 0; + if(preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE)) + { + foreach($entities[0] as $entity) + { + if($entity[1] + 1 - $entitiesLength <= $left) + { + $left--; + $entitiesLength += $this->uStrLen($entity[0]); + } + else + { + break; + } + } + } + $truncate .= $this->uSubStr($tag[3], 0, $left + $entitiesLength); + break; + } + else + { + $truncate .= $tag[3]; + $totalLength += $contentLength; + } + if($totalLength >= $length) + { + break; + } + } + if(!$exact) + { + $spacepos = $this->uStrrPos($truncate, ' '); + if(isset($spacepos)) + { + $bits = $this->uSubStr($truncate, $spacepos); + preg_match_all('/<\/([a-z]+)>/i', $bits, $droppedTags, PREG_SET_ORDER); + if(!empty($droppedTags)) + { + foreach($droppedTags as $closingTag) + { + if(!in_array($closingTag[1], $openTags)) + { + array_unshift($openTags, $closingTag[1]); + } + } + } + $truncate = $this->uSubStr($truncate, 0, $spacepos); + } + } + $truncate .= $ending; + foreach($openTags as $tag) + { + $truncate .= ''; + } + return $truncate; + } /** * Truncate a HTML string to a maximum length $len ­ append the string $more if it was truncated @@ -780,7 +883,7 @@ class e_parse * @param string $more [optional] String which will be added if truncation - default ' ... ' * @return string */ - public function html_truncate ($text, $len = 200, $more = ' ... ') + public function html_truncate_old ($text, $len = 200, $more = ' ... ') { $pos = 0; $curlen = 0;