Skip to content

Commit

Permalink
Merge pull request #2 from rgericke-elb/upgrade_to_work_with_current_…
Browse files Browse the repository at this point in the history
…versions

upgrade to work with current versions
  • Loading branch information
rgericke-elb authored Jun 13, 2023
2 parents f9ca0b2 + 6f90c4e commit 4c558a3
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 41 deletions.
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
"keywords": ["twig extension", "truncate", "twig"],
"type": "library",
"require": {
"php": ">=5.3.0",
"php": "^8.1",
"antoligy/dom-string-iterators": "^v1.0.0",
"twig/twig": ">=v1.0.0"
"twig/twig": ">=v1.0.0",
"ext-dom": "*",
"ext-libxml": "*"
},
"license": "MIT",
"authors": [
Expand Down
78 changes: 39 additions & 39 deletions src/TruncateExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,47 @@

namespace Bluetel\Twig;

use DOMElement;
use DOMNode;
use DOMText;
use DOMDocument;
use DOMWordsIterator;
use DOMLettersIterator;
use Twig_Extension;
use Twig_SimpleFilter;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;

/**
* TruncateExtension
* @author Alex Wilson <[email protected]>
* @license MIT
*/
class TruncateExtension extends Twig_Extension
class TruncateExtension extends AbstractExtension
{
/**
* @return array Returns the list of filters supplied by this extension.
* @return array<string, TwigFilter> Returns the list of filters supplied by this extension.
*/
public function getFilters()
public function getFilters(): array
{
$truncateWords = new Twig_SimpleFilter(
$truncateWords = new TwigFilter(
'truncate_words',
array($this, 'truncateWords'),
array(
'is_safe' => array('html'),
)
[$this, 'truncateWords'],
[
'is_safe' => ['html'],
]
);

$truncateLetters = new Twig_SimpleFilter(
$truncateLetters = new TwigFilter(
'truncate_letters',
array($this, 'truncateLetters'),
array(
'is_safe' => array('html'),
)
[$this, 'truncateLetters'],
[
'is_safe' => ['html'],
]
);

return array(
return [
'truncate_letters' => $truncateWords,
'truncate_words' => $truncateLetters,
);
];
}

/**
Expand All @@ -50,7 +52,7 @@ public function getFilters()
* @param string $ellipsis String to use as ellipsis (if any).
* @return string Safe truncated HTML.
*/
public function truncateWords($html, $limit = 0, $ellipsis = "")
public function truncateWords(string $html, int $limit = 0, string $ellipsis = ''): string
{
if ($limit <= 0) {
return $html;
Expand All @@ -59,7 +61,7 @@ public function truncateWords($html, $limit = 0, $ellipsis = "")
$dom = $this->htmlToDomDocument($html);

// Grab the body of our DOM.
$body = $dom->getElementsByTagName("body")->item(0);
$body = $dom->getElementsByTagName('body')->item(0);

// Iterate over words.
$words = new DOMWordsIterator($body);
Expand All @@ -77,7 +79,7 @@ public function truncateWords($html, $limit = 0, $ellipsis = "")
$curNode->nodeValue = substr(
$curNode->nodeValue,
0,
$words[$offset][1] + strlen($words[$offset][0])
$words[$offset][1] + \strlen($words[$offset][0])
);

self::removeProceedingNodes($curNode, $body);
Expand All @@ -91,7 +93,7 @@ public function truncateWords($html, $limit = 0, $ellipsis = "")

}

return $dom->saveHTML();
return (\is_string($dom->saveHTML())) ? $dom->saveHTML() : '';
}

/**
Expand All @@ -101,7 +103,7 @@ public function truncateWords($html, $limit = 0, $ellipsis = "")
* @param string $ellipsis String to use as ellipsis (if any).
* @return string Safe truncated HTML.
*/
public function truncateLetters($html, $limit = 0, $ellipsis = "")
public function truncateLetters(string $html, int $limit = 0, string $ellipsis = ''): string
{
if ($limit <= 0) {
return $html;
Expand All @@ -110,7 +112,7 @@ public function truncateLetters($html, $limit = 0, $ellipsis = "")
$dom = $this->htmlToDomDocument($html);

// Grab the body of our DOM.
$body = $dom->getElementsByTagName("body")->item(0);
$body = $dom->getElementsByTagName('body')->item(0);

// Iterate over letters.
$letters = new DOMLettersIterator($body);
Expand All @@ -131,15 +133,15 @@ public function truncateLetters($html, $limit = 0, $ellipsis = "")
}
}

return $dom->saveHTML();
return (\is_string($dom->saveHTML())) ? $dom->saveHTML() : '';
}

/**
* Builds a DOMDocument object from a string containing HTML.
* @param string HTML to load
* @param string $html HTML to load
* @returns DOMDocument Returns a DOMDocument object.
*/
public function htmlToDomDocument($html)
public function htmlToDomDocument(string $html): DOMDocument
{
// Transform multibyte entities which otherwise display incorrectly.
$html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');
Expand All @@ -157,25 +159,23 @@ public function htmlToDomDocument($html)

/**
* Removes all nodes after the current node.
* @param DOMNode|DOMElement $domNode
* @param DOMNode|DOMElement $topNode
* @return void
*/
private static function removeProceedingNodes($domNode, $topNode)
private static function removeProceedingNodes(DOMNode $domNode, ?DOMNode $topNode): void
{
$nextNode = $domNode->nextSibling;

if ($nextNode !== null) {
self::removeProceedingNodes($nextNode, $topNode);
$domNode->parentNode->removeChild($nextNode);
$domNode->parentNode?->removeChild($nextNode);
} else {
//scan upwards till we find a sibling
$curNode = $domNode->parentNode;
while ($curNode !== $topNode) {
while ($curNode !== $topNode && $topNode !== null) {
if ($curNode->nextSibling !== null) {
$curNode = $curNode->nextSibling;
self::removeProceedingNodes($curNode, $topNode);
$curNode->parentNode->removeChild($curNode);
$curNode?->parentNode->removeChild($curNode);
break;
}
$curNode = $curNode->parentNode;
Expand All @@ -185,15 +185,15 @@ private static function removeProceedingNodes($domNode, $topNode)

/**
* Inserts an ellipsis
* @param DOMNode|DOMElement $domNode Element to insert after.
* @param string $ellipsis Text used to suffix our document.
* @param DOMNode $domNode Element to insert after.
* @param string $ellipsis Text used to suffix our document.
* @return void
*/
private static function insertEllipsis($domNode, $ellipsis)
private static function insertEllipsis(DOMNode $domNode, string $ellipsis): void
{
$avoid = array('a', 'strong', 'em', 'h1', 'h2', 'h3', 'h4', 'h5'); //html tags to avoid appending the ellipsis to
$avoid = ['a', 'strong', 'em', 'h1', 'h2', 'h3', 'h4', 'h5']; //html tags to avoid appending the ellipsis to

if (in_array($domNode->parentNode->nodeName, $avoid) && $domNode->parentNode->parentNode !== null) {
if ($domNode->parentNode->parentNode !== null && in_array($domNode->parentNode->nodeName, $avoid)) {
// Append as text node to parent instead
$textNode = new DOMText($ellipsis);

Expand All @@ -205,15 +205,15 @@ private static function insertEllipsis($domNode, $ellipsis)

} else {
// Append to current node
$domNode->nodeValue = rtrim($domNode->nodeValue) . $ellipsis;
$domNode->nodeValue = rtrim($domNode->nodeValue ?? '') . $ellipsis;
}
}

/**
* Returns the name of this extension.
* @return string
*/
public function getName()
public function getName(): string
{
return 'truncate_extension';
}
Expand Down

0 comments on commit 4c558a3

Please sign in to comment.