Ver Mensaje Individual
  #1 (permalink)  
Antiguo 15/08/2010, 14:19
Avatar de destor77
destor77
 
Fecha de Ingreso: noviembre-2004
Ubicación: Gálvez, Santa Fe, Argentina
Mensajes: 2.654
Antigüedad: 19 años, 5 meses
Puntos: 43
cortar texto y tag html

Hola,
tengo la siguiente funcion para cortar texto a x cantidad de caracteres:
Código PHP:
Ver original
  1. /**
  2.      * funcion para cortar texto a la x cantidad de caracteres
  3.      * @param <string> $text
  4.      * @param <integer> $length
  5.      * @param <string> $ending
  6.      * @param <boolean> $exact
  7.      * @param <boolean> $considerHtml
  8.      * @return <string>
  9.      */
  10.     public function cortarTexto($text, $length = 100, $ending = "...", $exact = true, $considerHtml = false) {
  11.     if (is_array($ending)) {
  12.         extract($ending);
  13.     }
  14.     if ($considerHtml) {
  15.         if (mb_strlen(preg_replace("/<.*?>/", "", $text)) <= $length) {
  16.             return $text;
  17.         }
  18.         $totalLength = mb_strlen($ending);
  19.         $openTags = array();
  20.         $truncate = "";
  21.         preg_match_all("/(<\/?([\w+]+)[^>]*>)?([^<>]*)/", $text, $tags, PREG_SET_ORDER);
  22.         foreach ($tags as $tag) {
  23.             if (!preg_match("/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s", $tag[2])) {
  24.                 if (preg_match("/<[\w]+[^>]*>/s", $tag[0])) {
  25.                     array_unshift($openTags, $tag[2]);
  26.                 } else if (preg_match("/<\/([\w]+)[^>]*>/s", $tag[0], $closeTag)) {
  27.                     $pos = array_search($closeTag[1], $openTags);
  28.                     if ($pos !== false) {
  29.                         array_splice($openTags, $pos, 1);
  30.                     }
  31.                 }
  32.             }
  33.             $truncate .= $tag[1];
  34.  
  35.             $contentLength = mb_strlen(preg_replace("/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i", " ", $tag[3]));
  36.             if ($contentLength + $totalLength > $length) {
  37.                 $left = $length - $totalLength;
  38.                 $entitiesLength = 0;
  39.                 if (preg_match_all("/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i", $tag[3], $entities, PREG_OFFSET_CAPTURE)) {
  40.                     foreach ($entities[0] as $entity) {
  41.                         if ($entity[1] + 1 - $entitiesLength <= $left) {
  42.                             $left--;
  43.                             $entitiesLength += mb_strlen($entity[0]);
  44.                         } else {
  45.                             break;
  46.                         }
  47.                     }
  48.                 }
  49.  
  50.                 $truncate .= mb_substr($tag[3], 0 , $left + $entitiesLength);
  51.                 break;
  52.             } else {
  53.                 $truncate .= $tag[3];
  54.                 $totalLength += $contentLength;
  55.             }
  56.             if ($totalLength >= $length) {
  57.                 break;
  58.             }
  59.         }
  60.  
  61.     } else {
  62.         if (mb_strlen($text) <= $length) {
  63.             return $text;
  64.         } else {
  65.             $truncate = mb_substr($text, 0, $length - strlen($ending));
  66.         }
  67.     }
  68.     if (!$exact) {
  69.         $spacepos = mb_strrpos($truncate, " ");
  70.         if (isset($spacepos)) {
  71.             if ($considerHtml) {
  72.                 $bits = mb_substr($truncate, $spacepos);
  73.                 preg_match_all("/<\/([a-z]+)>/", $bits, $droppedTags, PREG_SET_ORDER);
  74.                 if (!empty($droppedTags)) {
  75.                     foreach ($droppedTags as $closingTag) {
  76.                         if (!in_array($closingTag[1], $openTags)) {
  77.                             array_unshift($openTags, $closingTag[1]);
  78.                         }
  79.                     }
  80.                 }
  81.             }
  82.             $truncate = mb_substr($truncate, 0, $spacepos);
  83.         }
  84.     }
  85.  
  86.     $truncate .= $ending;
  87.  
  88.     if ($considerHtml) {
  89.         foreach ($openTags as $tag) {
  90.             $truncate .= "";
  91.         }
  92.     }
  93.  
  94.     return $truncate;
  95.  
  96.  
  97.     }

La misma funciona de maravilla salvo por un pequeño inconveniente no me cierra correctamente los tags html. Es decir si yo tengo el texto:
Cita:
<p><strong><em>Esto es una prueba para que ver como funciona</em></strong></p>
y ejecuto la funciona asi:
Código PHP:
Ver original
  1. echo cortarTexto($cadena,10,'..',true,true);
me devuelve:
Cita:
<p><strong><em>Esto es una...
en vez de:
Cita:
<p><strong><em>Esto es una...</p></strong></em>
en que le estoy errando?