Skip to content

Commit

Permalink
Merge pull request yiisoft#13072 from developeruz/7727-truncate-html-…
Browse files Browse the repository at this point in the history
…leaves-extra-tags

Fixed truncateHtml leaving extra tags (yiisoft#7727)
  • Loading branch information
SilverFire authored Nov 28, 2016
2 parents b5b62e7 + 0545bb6 commit 457e924
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 5 deletions.
1 change: 1 addition & 0 deletions framework/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Yii Framework 2 Change Log
- Bug #12939: Hard coded table names for MSSQL in RBAC migration (arogachev)
- Bug #12974: Fixed incorrect order of migrations history in case `yii\console\controllers\MigrateController::$migrationNamespaces` is in use (evgen-d, klimov-paul)
- Bug #13071: Help option for commands was not working in modules (arogachev, haimanman)
- Bug #7727: Fixed truncateHtml leaving extra tags (developeruz)
- Enh #6809: Added `\yii\caching\Cache::$defaultDuration` property, allowing to set custom default cache duration (sdkiller)
- Enh #7333: Improved error message for `yii\di\Instance::ensure()` when a component does not exist (cebe)
- Enh #7420: Attributes for prompt generated with `renderSelectOptions` of `\yii\helpers\Html` helper (arogachev)
Expand Down
14 changes: 9 additions & 5 deletions framework/helpers/BaseStringHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,15 @@ protected static function truncateHtml($string, $count, $suffix, $encoding = fal
$config->set('Cache.SerializerPath', \Yii::$app->getRuntimePath());
$lexer = \HTMLPurifier_Lexer::create($config);
$tokens = $lexer->tokenizeHTML($string, $config, null);
$openTokens = 0;
$openTokens = [];
$totalCount = 0;
$truncated = [];
foreach ($tokens as $token) {
if ($token instanceof \HTMLPurifier_Token_Start) { //Tag begins
$openTokens++;
$truncated[] = $token;
if ($totalCount < $count) {
$openTokens[$token->name] = isset($openTokens[$token->name]) ? $openTokens[$token->name] + 1 : 1;
$truncated[] = $token;
}
} elseif ($token instanceof \HTMLPurifier_Token_Text && $totalCount <= $count) { //Text
if (false === $encoding) {
preg_match('/^(\s*)/um', $token->data, $prefixSpace) ?: $prefixSpace = ['',''];
Expand All @@ -174,8 +176,10 @@ protected static function truncateHtml($string, $count, $suffix, $encoding = fal
$totalCount += $currentCount;
$truncated[] = $token;
} elseif ($token instanceof \HTMLPurifier_Token_End) { //Tag ends
$openTokens--;
$truncated[] = $token;
if (!empty($openTokens[$token->name])) {
$openTokens[$token->name]--;
$truncated[] = $token;
}
} elseif ($token instanceof \HTMLPurifier_Token_Empty) { //Self contained tags, i.e. <img/> etc.
$truncated[] = $token;
}
Expand Down
2 changes: 2 additions & 0 deletions tests/framework/helpers/StringHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ public function testTruncate()
$this->assertEquals('<span><img src="image.png" />This is a test</span>...', StringHelper::truncate('<span><img src="image.png" />This is a test sentance</span>', 14, '...', null, true));
$this->assertEquals('<span><img src="image.png" />This is a test</span>...', StringHelper::truncate('<span><img src="image.png" />This is a test </span>sentance', 14, '...', null, true));
$this->assertEquals('<span><img src="image.png" />This is a test </span><strong>for</strong>...', StringHelper::truncate('<span><img src="image.png" />This is a test </span><strong>for a sentance</strong>', 18, '...', null, true));

$this->assertEquals('<p>This is a test</p><ul><li>bullet1</li><li>b</li></ul>...', StringHelper::truncate('<p>This is a test</p><ul><li>bullet1</li><li>bullet2</li><li>bullet3</li><li>bullet4</li></ul>', 22, '...', null, true));
}

public function testTruncateWords()
Expand Down

0 comments on commit 457e924

Please sign in to comment.