Zend Framework Source Code Snippets

View helper Truncate

Bookmark and Share
1
2
3
4
56
7
8
9
1011
12
13
14
1516
17
18
19
2021
22
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
4041
42
43
44
4546
47
48
49
5051
52
53
54
5556
57
58
59
6061
62
63
64
6566
67
68
69
7071
72
73
74
7576
77
78
79
8081
82
83
84
8586
87
88
89
9091
92
93
94
9596
97
<?php
/**
 * @copyright  2008, IgorN
 * @author     IgorN (progi2007@gmail.com)
 */class Application_Helper_View_Truncate 
{
        
/**
 * Truncates text. *
 * Cuts a string to the length of $length and replaces the last characters
 * with the 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 Ending to be appended to the trimmed string.
 * @param boolean $exact If false, $text will not be cut mid-word
 * @param boolean $considerHtml If true, HTML tags would be handled correctly
 * @return string Trimmed string. */
        public function truncate($text, $length = 150, $ending = '...', $exact = false, $considerHtml = false) 
        {
        if ($considerHtml) {
            if (strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {                return $text;
            }
            
            preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
                $total_length = strlen($ending);
            $open_tags = array();
            $truncate = '';
            
            foreach ($lines as $line_matchings) {                if (!empty($line_matchings[1])) {
                    if (preg_match('/^<(s*.+?/s*|s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(s.+?)?)>$/is', $line_matchings[1])) {
                    } else if (preg_match('/^<s*/([^s]+?)s*>$/s', $line_matchings[1], $tag_matchings)) {
                        $pos = array_search($tag_matchings[1], $open_tags);
                        if ($pos !== false) {                            unset($open_tags[$pos]);
                        }
                    } else if (preg_match('/^<s*([^s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) {
                        array_unshift($open_tags, strtolower($tag_matchings[1]));
                    }                    $truncate .= $line_matchings[1];
                }
                $content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
                if ($total_length+$content_length > $length) {
                    $left = $length - $total_length;                    $entities_length = 0;
                    if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $line_matchings[2], $entities, PREG_OFFSET_CAPTURE)) {
                        foreach ($entities[0] as $entity) {
                            if ($entity[1]+1-$entities_length <= $left) {
                                $left--;                                $entities_length += strlen($entity[0]);
                            } else {
                                break;
                            }
                        }                    }
                    $truncate .= substr($line_matchings[2], 0, $left+$entities_length);
                    break;
                } else {
                    $truncate .= $line_matchings[2];                    $total_length += $content_length;
                }
                if($total_length >= $length) {
                    break;
                }            }
        } else {
            if (strlen($text) <= $length) {
                return $text;
            } else {                $truncate = substr($text, 0, $length - strlen($ending));
            }
        }
        
                if (!$exact) {                        $spacepos = strrpos($truncate, ' ');
                        if (isset($spacepos)) {
                                $truncate = substr($truncate, 0, $spacepos);
                        }
                }                $truncate .= $ending;
                
        if($considerHtml) {
            foreach ($open_tags as $tag) {
                $truncate .= '</' . $tag . '>';            }
        }
                
                return $truncate;   
        }}
?>

Comments

leek leek
1 year ago

Might be a good idea to switch this:

$ending = '...'

to

$ending = '&hellip;'

and move that argument to the end of the list.

IgorN IgorN
1 year ago

Good Idea :)

Snowcore Snowcore
1 year ago

Nice thing, thanks.

panosru panosru
2 months ago

In case $considerHtml equals to false then I think that it would be better to strip out all html tags so in case the text would start with something like this:

<br /><br /><strong>Some Text here and etc etc</strong> the two breaks will render and they may break your layout so I would suggest to change this:

} else {
if ( strlen ( $text ) <= $length ) {

Into this:


} else {
$text = trim(preg_replace(\'%</?\\w+((\\s+\\w+(\\s*=\\s*(?:\".*?\"|\\\'.*?\\\'|[^\\\'\">\\s]+))?)+\\s*|\\s*)/?>%ix\', \'\', $text));
if ( strlen ( $text ) <= $length ) {

You must login before commenting on a snippet. If you do not have an account, please register.

Snippet description

Snippet details

Created:
IgorN IgorN
1 year ago
Edited:
IgorN IgorN
1 year ago
Revision Id:
21
Edit Message:
Initial Release
Tags:
truncate
Comments:
4
Views:
1582
Points:
0 (0 votes)

History

r21

Initial Release

IgorN IgorN
1 year ago