File indexing completed on 2024-05-12 17:24:24

0001 <?php
0002 
0003 /**
0004  *  ocs-apiserver
0005  *
0006  *  Copyright 2016 by pling GmbH.
0007  *
0008  *    This file is part of ocs-apiserver.
0009  *
0010  *    This program is free software: you can redistribute it and/or modify
0011  *    it under the terms of the GNU Affero General Public License as
0012  *    published by the Free Software Foundation, either version 3 of the
0013  *    License, or (at your option) any later version.
0014  *
0015  *    This program is distributed in the hope that it will be useful,
0016  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
0017  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0018  *    GNU Affero General Public License for more details.
0019  *
0020  *    You should have received a copy of the GNU Affero General Public License
0021  *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
0022  **/
0023 class Application_View_Helper_Truncate extends Zend_View_Helper_Abstract
0024 {
0025 
0026     /**
0027      * Truncates text.
0028      *
0029      * Cuts a string to the length of $length and replaces the last characters
0030      * with the ending if the text is longer than length.
0031      *
0032      * @param string  $text         String to truncate.
0033      * @param integer $length       Length of returned string, including ellipsis.
0034      * @param string  $ending       Ending to be appended to the trimmed string.
0035      * @param boolean $exact        If false, $text will not be cut mid-word
0036      * @param boolean $considerHtml If true, HTML tags would be handled correctly
0037      *
0038      * @return string Trimmed string.
0039      */
0040     public function truncate($text, $length = 150, $ending = '...', $exact = false, $considerHtml = false)
0041     {
0042         if (strlen($text) == 0) {
0043             return '';
0044         }
0045 
0046         $total_length = strlen($ending);
0047         $open_tags = array();
0048         $truncate = '';
0049 
0050         if ($considerHtml) {
0051             if (strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
0052                 return $text;
0053             }
0054 
0055             preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
0056 
0057             foreach ($lines as $line_matchings) {
0058                 if (!empty($line_matchings[1])) {
0059                     if (preg_match('/^<(s*.+?\/s*|s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(s.+?)?)>$/is',
0060                         $line_matchings[1])) {
0061                     } else if (preg_match('/^<s*\/([^s]+?)s*>$/s', $line_matchings[1], $tag_matchings)) {
0062                         $pos = array_search($tag_matchings[1], $open_tags);
0063                         if ($pos !== false) {
0064                             unset($open_tags[$pos]);
0065                         }
0066                     } else if (preg_match('/^<s*([^s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) {
0067                         array_unshift($open_tags, strtolower($tag_matchings[1]));
0068                     }
0069                     $truncate .= $line_matchings[1];
0070                 }
0071                 $content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
0072                 if ($total_length + $content_length > $length) {
0073                     $left = $length - $total_length;
0074                     $entities_length = 0;
0075                     if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $line_matchings[2], $entities,
0076                         PREG_OFFSET_CAPTURE)) {
0077                         foreach ($entities[0] as $entity) {
0078                             if ($entity[1] + 1 - $entities_length <= $left) {
0079                                 $left--;
0080                                 $entities_length += strlen($entity[0]);
0081                             } else {
0082                                 break;
0083                             }
0084                         }
0085                     }
0086                     $truncate .= substr($line_matchings[2], 0, $left + $entities_length);
0087                     break;
0088                 } else {
0089                     $truncate .= $line_matchings[2];
0090                     $total_length += $content_length;
0091                 }
0092                 if ($total_length >= $length) {
0093                     break;
0094                 }
0095             }
0096         } else {
0097             if (strlen($text) <= $length) {
0098                 return $text;
0099             } else {
0100                 $truncate = substr($text, 0, $length - strlen($ending));
0101             }
0102         }
0103 
0104         if (!$exact) {
0105             $spacepos = strrpos($truncate, ' ');
0106             if ($spacepos !== false) {
0107                 $truncate = substr($truncate, 0, $spacepos);
0108             }
0109         }
0110         $truncate .= $ending;
0111 
0112         if ($considerHtml) {
0113             foreach ($open_tags as $tag) {
0114                 $truncate .= '</' . $tag . '>';
0115             }
0116         }
0117 
0118         return $truncate;
0119     }
0120 
0121 }