Bug #18535 » bug_7984_typo3_4-2-0RC1.diff
typo3_src-4.2.0RC1.new/typo3/sysext/cms/tslib/class.tslib_content.php 2008-04-10 11:56:05.000000000 +0200 | ||
---|---|---|
* @access private
|
||
* @see stdWrap()
|
||
*/
|
||
function crop($content,$options) {
|
||
function crop($content,$options) {
|
||
$options = explode('|',$options);
|
||
$chars = intval($options[0]);
|
||
$afterstring = trim($options[1]);
|
||
$crop2space = trim($options[2]);
|
||
if ($chars) {
|
||
if (strlen($content)>abs($chars)) {
|
||
if ($chars<0) {
|
||
$content = $GLOBALS['TSFE']->csConvObj->substr($GLOBALS['TSFE']->renderCharset,$content,$chars);
|
||
$trunc_at = strpos($content, ' ');
|
||
$content = ($trunc_at&&$crop2space) ? $afterstring.substr($content,$trunc_at) : $afterstring.$content;
|
||
$replacementForEllipsis = trim($options[1]);
|
||
$crop2space = isset($options[2]) ? trim($options[2]) : 0;
|
||
// split $content into an array (even items in the array are outside the tags, odd numbers are tag-blocks)
|
||
$tags= 'a|b|blockquote|body|div|em|font|form|h1|h2|h3|h4|h5|h6|i|li|map|ol|option|p|pre|sub|sup|select|span|strong|table|td|textarea|tr|u|ul|br|hr|img|input|area|link';
|
||
$tagsRegEx = "
|
||
(
|
||
(?:
|
||
<!--.*?-->
|
||
)
|
||
|
|
||
</?(?:". $tags . ")+
|
||
(?:
|
||
(?:
|
||
\s+\w+
|
||
(?:
|
||
\s*=?\s*
|
||
(?>
|
||
\".*?\"
|
||
|
|
||
'.*?'
|
||
|
|
||
[^'\">\s]+
|
||
)
|
||
)?
|
||
)+
|
||
\s*|\s*
|
||
)
|
||
/?>
|
||
)";
|
||
$splittedContent = preg_split("#" . $tagsRegEx . "#ux", $content, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||
// reverse array if we are cropping from right
|
||
if ($chars < 0) $splittedContent = array_reverse($splittedContent);
|
||
// crop the text (chars of tag-blocks are not counted)
|
||
$strLen = 0;
|
||
$croppedOffset = NULL; // offset of the content item which was cropped
|
||
for ($offset = 0; $offset < count($splittedContent); $offset++) {
|
||
if ($offset%2 === 0) {
|
||
$thisStrLen = $GLOBALS['TSFE']->csConvObj->strlen($GLOBALS['TSFE']->renderCharset, html_entity_decode($splittedContent[$offset],ENT_COMPAT,$GLOBALS['TSFE']->renderCharset));
|
||
if (($strLen + $thisStrLen > abs($chars))) {
|
||
$croppedOffset = $offset;
|
||
$cropPosition = abs($chars) - $strLen;
|
||
if ($crop2space) {
|
||
$cropRegEx = $chars < 0 ? '#(?<=\s).{0,' . $cropPosition . '}$#ui' : '#^.{0,' . $cropPosition . '}(?=\s)#ui';
|
||
} else {
|
||
$cropRegEx = $chars < 0 ? '#(.(?![^&\s]{2,7};)|(&[^&\s;]{2,7};)){0,' . $cropPosition . '}$#ui' : '#^(.(?![^&\s]{2,7};)|(&[^&\s;]{2,7};)){0,' . $cropPosition . '}#ui';
|
||
}
|
||
if (preg_match($cropRegEx, $splittedContent[$offset], $croppedMatch)) $splittedContent[$offset] = $croppedMatch[0];
|
||
break;
|
||
} else {
|
||
$content = $GLOBALS['TSFE']->csConvObj->substr($GLOBALS['TSFE']->renderCharset,$content,0,$chars);
|
||
$trunc_at = strrpos($content, ' ');
|
||
$content = ($trunc_at&&$crop2space) ? substr($content, 0, $trunc_at).$afterstring : $content.$afterstring;
|
||
$strLen += $thisStrLen;
|
||
}
|
||
}
|
||
}
|
||
return $content;
|
||
// close cropped tags
|
||
$closingTags = array();
|
||
if($croppedOffset !== NULL) {
|
||
$tagName = '';
|
||
$openingTagRegEx = '#^<(\w+)(?:\s|>)#u';
|
||
$closingTagRegEx = '#^</(\w+)(?:\s|>)#u';
|
||
for ($offset=$croppedOffset-1; $offset >= 0; $offset = $offset-2) {
|
||
if (preg_match('&/>$&', $splittedContent[$offset])) continue; // ignore empty element tags (e.g. <br />)
|
||
preg_match($chars < 0 ? $closingTagRegEx : $openingTagRegEx, $splittedContent[$offset], $matches);
|
||
$tagName = isset($matches[1]) ? $matches[1] : NULL;
|
||
if ($tagName !== NULL) {
|
||
// seek for the closing (or opening) tag
|
||
$seekingTagName = '';
|
||
for ($seekingOffset = $offset + 2; $seekingOffset < count($splittedContent); $seekingOffset = $seekingOffset + 2) {
|
||
preg_match($chars < 0 ? $openingTagRegEx : $closingTagRegEx, $splittedContent[$seekingOffset], $matches);
|
||
$seekingTagName = isset($matches[1]) ? $matches[1] : NULL;
|
||
if ($tagName === $seekingTagName) { // we found a matching tag
|
||
// add closing tag only if it occurs after the cropped content item
|
||
if ($seekingOffset > $croppedOffset) $closingTags[] = $splittedContent[$seekingOffset];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
array_splice($splittedContent, $croppedOffset + 1); // drop the cropped items of the content array
|
||
}
|
||
$splittedContent = array_merge($splittedContent, array($croppedOffset !== NULL ? $replacementForEllipsis : ''), $closingTags);
|
||
// reverse array once again if we are cropping from the end
|
||
if ($chars < 0) $splittedContent = array_reverse($splittedContent);
|
||
return implode('', $splittedContent);
|
||
}
|
||
/**
|