Beispiel #1
0
 /**
  * Создание фрагмента для сниппета
  *
  * @param string $sText
  * @param array  $aSet
  * @param int    $nPos
  * @param int    $nLen
  *
  * @return string
  */
 protected function _makeSnippetFragment($sText, $aSet, $nPos, $nLen)
 {
     $nLenWord = $nLen;
     $nLenText = mb_strlen($sText);
     $nShippetOffset = floor(($this->nShippetLength - $nLenWord) / 2);
     // начало фрагмена
     if ($nPos < $nShippetOffset) {
         $nFragBegin = 0;
     } else {
         $nFragBegin = $nPos - $nShippetOffset;
     }
     // конец фрагмента
     if ($nPos + $nLenWord + $nShippetOffset > $nLenText) {
         $nFragEnd = $nLenText;
     } else {
         $nFragEnd = $nPos + $nLenWord + $nShippetOffset;
     }
     // Выравнивание по границе слов
     $sPattern = '/' . $this->sPatternW . '+$/uisxSXU';
     if ($nFragBegin > 0 && mb_preg_match($sPattern, mb_substr($sText, 0, $nFragBegin), $m, PREG_OFFSET_CAPTURE)) {
         $nFragBegin -= mb_strlen($m[0][0]);
     }
     $sPattern = '/^' . $this->sPatternW . '+/uisxSXU';
     if ($nFragEnd < $nLenText && mb_preg_match($sPattern, mb_substr($sText, $nFragEnd), $m, PREG_OFFSET_CAPTURE)) {
         $nFragEnd += mb_strlen($m[0][0]) + $m[0][1];
     }
     // Обрезание по максимальной длине
     if ($this->nShippetMaxLength > 0 && ($nOver = $nFragEnd - $nFragBegin - $this->nShippetMaxLength) > 0) {
         $nFragBegin -= floor($nOver / 2);
         if ($nFragBegin < 0) {
             $nFragBegin = 0;
         }
         if ($nFragBegin > $nPos) {
             $nFragBegin = $nPos;
         }
         $nFragEnd = $nFragBegin + $this->nShippetMaxLength;
         if ($nFragEnd < $nPos + $nLenWord) {
             $nFragEnd = $nPos + $nLenWord;
         }
     }
     $sFragment = '';
     // * Укладываем слова из одного сета в один фрагмент
     $iBegin = $nFragBegin;
     foreach ($aSet as $aWord) {
         $iWordPos = $aWord['pos'];
         $sFragment .= str_replace('>', '&gt;', str_replace('<', '&lt;', mb_substr($sText, $iBegin, $iWordPos - $iBegin)));
         $sFragment .= $this->sSnippetBeforeMatch . $aWord['txt'] . $this->sSnippetAfterMatch;
         $iBegin = $iWordPos + $aWord['len'];
     }
     $sFragment .= str_replace('>', '&gt;', str_replace('<', '&lt;', mb_substr($sText, $iBegin, $nFragEnd - $iBegin)));
     $sFragment = ($nFragBegin > 0 ? '&hellip;' : '') . $sFragment . ($nFragEnd < $nLenText ? '&hellip;' : '');
     $sFragment = str_replace('&lt;br/&gt;', '', $sFragment);
     return $sFragment;
 }
Beispiel #2
0
 /** ************************************************************************************************************
  * Function to truncate and shorten text
  *
  * @param string $html The html code which should be shortened
  * @param int $length The length to which the text should be shortened
  * @param bool skip If this value is true the truncate will be skipped (nothing will be done)
  * @param bool perserve_tags Specifies if html tags should be preserved or if only the text should be shortened
  ***************************************************************************************************************/
 public function truncate($html, $length, $skip = false, $preserve_tags = true)
 {
     mb_internal_encoding("UTF-8");
     if (0 >= $length || mb_strlen($html) <= $length || $skip) {
         // do nothing
         return $html;
     } elseif (!$preserve_tags) {
         // only shorten text
         return mb_substr($html, 0, $length);
     } else {
         // truncate with preserving html tags
         $printedLength = 0;
         $position = 0;
         $tags = array();
         $out = '';
         while ($printedLength < $length && mb_preg_match('{</?([a-z]+\\d?)[^>]*>|&#?[a-zA-Z0-9]+;}', $html, $match, PREG_OFFSET_CAPTURE, $position)) {
             list($tag, $tagPosition) = $match[0];
             // Print text leading up to the tag
             $str = mb_substr($html, $position, $tagPosition - $position);
             if ($printedLength + mb_strlen($str) > $length) {
                 $out .= mb_substr($str, 0, $length - $printedLength);
                 $printedLength = $length;
                 break;
             }
             $out .= $str;
             $printedLength += mb_strlen($str);
             if ('&' == $tag[0]) {
                 // Handle the entity
                 $out .= $tag;
                 $printedLength++;
             } else {
                 // Handle the tag
                 $tagName = $match[1][0];
                 if ('/' == $tag[1]) {
                     // This is a closing tag
                     $openingTag = array_pop($tags);
                     assert($openingTag == $tagName);
                     // check that tags are properly nested
                     $out .= $tag;
                 } else {
                     if ('/' == $tag[mb_strlen($tag) - 2]) {
                         // Self-closing tag
                         $out .= $tag;
                     } else {
                         // Opening tag
                         $out .= $tag;
                         $tags[] = $tagName;
                     }
                 }
             }
             // Continue after the tag
             $position = $tagPosition + mb_strlen($tag);
         }
         // Print any remaining text
         if ($printedLength < $length && $position < mb_strlen($html)) {
             $out .= mb_substr($html, $position, $length - $printedLength);
         }
         // Print ellipsis ("...") if the html is not complete
         if (mb_strlen($html) != $position) {
             $out .= ' &hellip;';
         }
         // Close any open tags.
         while (!empty($tags)) {
             $out .= '</' . array_pop($tags) . '>';
         }
         return $out;
     }
 }
Beispiel #3
0
 /** **************************************************************************************************
  * Truncate HTML, close opened tags
  *
  * @param int $max_length           The length (number of characters) to which the text will be
  *                                  shortened. With "0" the full text will be returned. With "auto"
  *                                  also the complete text will be used, but a wrapper div will be
  *                                  added which shortens the text to 1 full line via css.
  * @param string $html              The html code which should be shortened.
  * @param string $wrapper_type      Defines which kind of wrapper shall be added around the html code
  *                                  if a manual length shall be used. The possible values are "none",
  *                                  "div" and "span". With "none" no wrapper will be added, "div" and
  *                                  "span" are the 2 available wrapper types.
  *                                  If max_length is set to auto a div is mandatory and will be added
  *                                  always, independent of the given value.
  * @param array $wrapper_attributes Additional attributes for the wrapper element. The array
  *                                  key defines the attribute name.
  *****************************************************************************************************/
 private function truncate($max_length, $html, $wrapper_type = 'none', $wrapper_attributes = array())
 {
     // Apply wrapper and add required css for autolength (if required)
     $autolength = 'auto' == $max_length ? true : false;
     if ($autolength) {
         $wrapper_type = 'div';
     } elseif ('div' != $wrapper_type && 'span' != $wrapper_type) {
         $wrapper_type = 'none';
     }
     if ('none' != $wrapper_type) {
         $wrapper_text = '<' . $wrapper_type;
         foreach ($wrapper_attributes as $name => $value) {
             $wrapper_text .= ' ' . $name . '="' . $value . '"';
         }
         if ($autolength) {
             $wrapper_text .= ' style="white-space:nowrap; overflow:hidden; text-overflow:ellipsis"';
         }
         $html = $wrapper_text . '>' . $html . '</' . $wrapper_type . '>';
     }
     // Apply manual length
     mb_internal_encoding("UTF-8");
     if (is_numeric($max_length) && 0 < $max_length && mb_strlen($html) > $max_length) {
         $printedLength = 0;
         $position = 0;
         $tags = array();
         $out = '';
         while ($printedLength < $max_length && mb_preg_match('{</?([a-z]+\\d?)[^>]*>|&#?[a-zA-Z0-9]+;}', $html, $match, PREG_OFFSET_CAPTURE, $position)) {
             list($tag, $tagPosition) = $match[0];
             // Print text leading up to the tag
             $str = mb_substr($html, $position, $tagPosition - $position);
             if ($printedLength + mb_strlen($str) > $max_length) {
                 $out .= mb_substr($str, 0, $max_length - $printedLength);
                 $printedLength = $max_length;
                 break;
             }
             $out .= $str;
             $printedLength += mb_strlen($str);
             if ('&' == $tag[0]) {
                 // Handle the entity
                 $out .= $tag;
                 $printedLength++;
             } else {
                 // Handle the tag
                 $tagName = $match[1][0];
                 if ('/' == $tag[1]) {
                     // This is a closing tag
                     $openingTag = array_pop($tags);
                     assert($openingTag == $tagName);
                     // check that tags are properly nested
                     $out .= $tag;
                 } else {
                     if ('/' == $tag[mb_strlen($tag) - 2]) {
                         // Self-closing tag
                         $out .= $tag;
                     } else {
                         // Opening tag
                         $out .= $tag;
                         $tags[] = $tagName;
                     }
                 }
             }
             // Continue after the tag
             $position = $tagPosition + mb_strlen($tag);
         }
         // Print any remaining text
         if ($printedLength < $max_length && $position < mb_strlen($html)) {
             $out .= mb_substr($html, $position, $max_length - $printedLength);
         }
         // Print ellipsis ("...") if the html is not complete
         if (mb_strlen($html) != $position) {
             $out .= ' &hellip;';
         }
         // Close any open tags.
         while (!empty($tags)) {
             $out .= '</' . array_pop($tags) . '>';
         }
         return $out;
     }
     return $html;
 }
Beispiel #4
0
 /**
  * Создание фрагмента для сниппета
  */
 protected function MakeSnippetFragment($text, $set, $pos, $len)
 {
     $fragment = '';
     $lenWord = $len;
     $lenText = mb_strlen($text);
     $this->nShippetOffset = floor(($this->nShippetLength - $lenWord) / 2);
     // начало фрагмена
     if ($pos < $this->nShippetOffset) {
         $fragBegin = 0;
     } else {
         $fragBegin = $pos - $this->nShippetOffset;
     }
     // конец фрагмента
     if ($pos + $lenWord + $this->nShippetOffset > $lenText) {
         $fragEnd = $lenText;
     } else {
         $fragEnd = $pos + $lenWord + $this->nShippetOffset;
     }
     // Выравнивание по границе слов
     if ($fragBegin > 0 && mb_preg_match('/' . $this->sPatternW . '+$/uisxSX', mb_substr($text, 0, $fragBegin), $m)) {
         $fragBegin -= mb_strlen($m[0][0]);
     }
     if ($fragEnd < $lenText && mb_preg_match('/' . $this->sPatternW . '+/uisxSX', mb_substr($text, $fragEnd), $m)) {
         $fragEnd += mb_strlen($m[0][0]) + $m[0][1];
     }
     // Обрезание по максимальной длине
     if ($this->nShippetMaxLength > 0 && ($nOver = $fragEnd - $fragBegin - $this->nShippetMaxLength) > 0) {
         $fragBegin -= floor($nOver / 2);
         if ($fragBegin > $pos) {
             $fragBegin = $pos;
         }
         $fragEnd = $fragBegin + $this->nShippetMaxLength;
         if ($fragEnd < $pos + $lenWord) {
             $fragEnd = $pos + $lenWord;
         }
     }
     $fragment = '';
     // * Укладываем слова из одного сета в один фрагмент
     $begin = $fragBegin;
     foreach ($set as $word) {
         $pos = $word['pos'];
         $fragment .= str_replace('>', '&gt;', str_replace('<', '&lt;', mb_substr($text, $begin, $pos - $begin)));
         $fragment .= $this->sSnippetBeforeMatch . $word['txt'] . $this->sSnippetAfterMatch;
         $begin = $pos + $word['len'];
     }
     $fragment .= str_replace('>', '&gt;', str_replace('<', '&lt;', mb_substr($text, $begin, $fragEnd - $begin)));
     $fragment = ($fragBegin > 0 ? '&hellip;' : '') . $fragment . ($fragEnd < $lenText ? '&hellip;' : '');
     $fragment = str_replace('&lt;br/&gt;', '', $fragment);
     return $fragment;
 }