From 4e7e06fa9f3e330884acb2c2dbcc239b32f3470e Mon Sep 17 00:00:00 2001 From: Kyle Robinson Young Date: Sat, 24 Dec 2011 21:25:07 -0800 Subject: [PATCH 1/2] Prevent TextHelper::truncate() from breaking HTML Fixes #2397 --- .../Test/Case/View/Helper/TextHelperTest.php | 47 ++++++++++++++++++- lib/Cake/View/Helper/TextHelper.php | 26 ++++++---- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/lib/Cake/Test/Case/View/Helper/TextHelperTest.php b/lib/Cake/Test/Case/View/Helper/TextHelperTest.php index a10a211dc..54752c548 100644 --- a/lib/Cake/Test/Case/View/Helper/TextHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/TextHelperTest.php @@ -60,7 +60,7 @@ class TextHelperTest extends CakeTestCase { $text5 = '01234567890'; $text6 = '

Extra dates have been announced for this year\'s tour.

Tickets for the new shows in

'; $text7 = 'El moño está en el lugar correcto. Eso fue lo que dijo la niña, ¿habrá dicho la verdad?'; - $text8 = 'Vive la R'.chr(195).chr(169).'publique de France'; + $text8 = 'Vive la R' . chr(195) . chr(169) . 'publique de France'; $text9 = 'НОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь'; $this->assertSame($this->Text->truncate($text1, 15), 'The quick br...'); @@ -86,6 +86,51 @@ class TextHelperTest extends CakeTestCase { $this->assertSame($this->Text->truncate($text7, 15), 'El moño está...'); $this->assertSame($this->Text->truncate($text8, 15), 'Vive la R'.chr(195).chr(169).'pu...'); $this->assertSame($this->Text->truncate($text9, 10), 'НОПРСТУ...'); + + $text = '

Iamatestwithnospacesandhtml

'; + $result = $this->Text->truncate($text, 10, array( + 'ending' => '...', + 'exact' => false, + 'html' => true + )); + $expected = '

...

'; + $this->assertEquals($expected, $result); + + $text = '

El biógrafo de Steve Jobs, Walter +Isaacson, explica porqué Jobs le pidió que le hiciera su biografía en +este artículo de El País.

+

Por qué Steve era distinto.

+

http://www.elpais.com/articulo/primer/plano/ +Steve/era/distinto/elpepueconeg/20111009elpneglse_4/Tes

+

Ya se ha publicado la biografía de +Steve Jobs escrita por Walter Isaacson "Steve Jobs by Walter +Isaacson", aquí os dejamos la dirección de amazon donde +podeís adquirirla.

+

http://www.amazon.com/Steve- +Jobs-Walter-Isaacson/dp/1451648537

'; + $result = $this->Text->truncate($text, 500, array( + 'ending' => '... ', + 'exact' => false, + 'html' => true + )); + $expected = '

El biógrafo de Steve Jobs, Walter +Isaacson, explica porqué Jobs le pidió que le hiciera su biografía en +este artículo de El País.

+

Por qué Steve era distinto.

+

http://www.elpais.com/articulo/primer/plano/ +Steve/era/distinto/elpepueconeg/20111009elpneglse_4/Tes

+

Ya se ha publicado la biografía de +Steve Jobs escrita por Walter Isaacson "Steve Jobs by Walter +Isaacson", aquí os dejamos la dirección de amazon donde +podeís adquirirla.

+

...

'; + $this->assertEquals($expected, $result); } /** diff --git a/lib/Cake/View/Helper/TextHelper.php b/lib/Cake/View/Helper/TextHelper.php index ee11b037b..2dbb28df4 100644 --- a/lib/Cake/View/Helper/TextHelper.php +++ b/lib/Cake/View/Helper/TextHelper.php @@ -275,20 +275,26 @@ class TextHelper extends AppHelper { } if (!$exact) { $spacepos = mb_strrpos($truncate, ' '); - if (isset($spacepos)) { - if ($html) { - $bits = mb_substr($truncate, $spacepos); - preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER); - if (!empty($droppedTags)) { - foreach ($droppedTags as $closingTag) { - if (!in_array($closingTag[1], $openTags)) { - array_unshift($openTags, $closingTag[1]); - } + if ($html) { + $truncateCheck = mb_substr($truncate, 0, $spacepos); + $lastOpenTag = mb_strrpos($truncateCheck, '<'); + $lastCloseTag = mb_strrpos($truncateCheck, '>'); + if ($lastOpenTag > $lastCloseTag) { + preg_match_all('/<[\w]+[^>]*>/s', $truncate, $lastTagMatches); + $lastTag = array_pop($lastTagMatches[0]); + $spacepos = mb_strrpos($truncate, $lastTag) + mb_strlen($lastTag); + } + $bits = mb_substr($truncate, $spacepos); + preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER); + if (!empty($droppedTags)) { + foreach ($droppedTags as $closingTag) { + if (!in_array($closingTag[1], $openTags)) { + array_unshift($openTags, $closingTag[1]); } } } - $truncate = mb_substr($truncate, 0, $spacepos); } + $truncate = mb_substr($truncate, 0, $spacepos); } $truncate .= $ending; From acca796d10255fc7ebbf8a51dcc1f29baf87234b Mon Sep 17 00:00:00 2001 From: Kyle Robinson Young Date: Sun, 25 Dec 2011 09:10:50 -0800 Subject: [PATCH 2/2] Fix tag order when closing open tags with TextHelper::truncate() --- lib/Cake/Test/Case/View/Helper/TextHelperTest.php | 2 +- lib/Cake/View/Helper/TextHelper.php | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Test/Case/View/Helper/TextHelperTest.php b/lib/Cake/Test/Case/View/Helper/TextHelperTest.php index 54752c548..81c36dcd6 100644 --- a/lib/Cake/Test/Case/View/Helper/TextHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/TextHelperTest.php @@ -129,7 +129,7 @@ Steve/era/distinto/elpepueconeg/20111009elpneglse_4/Tes

Steve Jobs escrita por Walter Isaacson "Steve Jobs by Walter Isaacson", aquí os dejamos la dirección de amazon donde podeís adquirirla.

-

...

'; +

...

'; $this->assertEquals($expected, $result); } diff --git a/lib/Cake/View/Helper/TextHelper.php b/lib/Cake/View/Helper/TextHelper.php index 2dbb28df4..fc6fc10d3 100644 --- a/lib/Cake/View/Helper/TextHelper.php +++ b/lib/Cake/View/Helper/TextHelper.php @@ -287,9 +287,15 @@ class TextHelper extends AppHelper { $bits = mb_substr($truncate, $spacepos); preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER); if (!empty($droppedTags)) { - foreach ($droppedTags as $closingTag) { - if (!in_array($closingTag[1], $openTags)) { - array_unshift($openTags, $closingTag[1]); + if (!empty($openTags)) { + foreach ($droppedTags as $closingTag) { + if (!in_array($closingTag[1], $openTags)) { + array_unshift($openTags, $closingTag[1]); + } + } + } else { + foreach ($droppedTags as $closingTag) { + array_push($openTags, $closingTag[1]); } } }