I am trying to cut off text after 236 chars without cutting words in half and preserving html tags. This is what I am using right now:
$shortdesc = $_helper-
This will work with Unicode (from @nice ass answer):
class Html
{
protected
$reachedLimit = false,
$totalLen = 0,
$maxLen = 25,
$toRemove = [];
public static function trim($html, $maxLen = 25)
{
$dom = new \DOMDocument();
$dom->loadHTML('' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$instance = new static();
$toRemove = $instance->walk($dom, $maxLen);
// remove any nodes that exceed limit
foreach ($toRemove as $child) {
$child->parentNode->removeChild($child);
}
return $dom->saveHTML();
}
protected function walk(\DOMNode $node, $maxLen)
{
if ($this->reachedLimit) {
$this->toRemove[] = $node;
} else {
// only text nodes should have text,
// so do the splitting here
if ($node instanceof \DOMText) {
$this->totalLen += $nodeLen = mb_strlen($node->nodeValue);
// use mb_strlen / mb_substr for UTF-8 support
if ($this->totalLen > $maxLen) {
dump($node->nodeValue);
$node->nodeValue = mb_substr($node->nodeValue, 0, $nodeLen - ($this->totalLen - $maxLen)) . '...';
$this->reachedLimit = true;
}
}
// if node has children, walk its child elements
if (isset($node->childNodes)) {
foreach ($node->childNodes as $child) {
$this->walk($child, $maxLen);
}
}
}
return $this->toRemove;
}
}