From 1cfaeec378a277b4be6d4a17abfc10c3177a6b22 Mon Sep 17 00:00:00 2001 From: Fran Moreno Date: Sat, 8 Feb 2020 08:50:31 +0100 Subject: [PATCH] [String] Allow to keep the last word when truncating a text --- src/Symfony/Component/String/AbstractString.php | 6 +++++- src/Symfony/Component/String/CHANGELOG.md | 7 ++++--- .../Component/String/Tests/AbstractAsciiTestCase.php | 9 +++++++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/String/AbstractString.php b/src/Symfony/Component/String/AbstractString.php index bdae34dd8ba7..c11a93062815 100644 --- a/src/Symfony/Component/String/AbstractString.php +++ b/src/Symfony/Component/String/AbstractString.php @@ -620,7 +620,7 @@ abstract public function trimStart(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FE /** * @return static */ - public function truncate(int $length, string $ellipsis = ''): self + public function truncate(int $length, string $ellipsis = '', bool $cut = true): self { $stringLength = $this->length(); @@ -634,6 +634,10 @@ public function truncate(int $length, string $ellipsis = ''): self $ellipsisLength = 0; } + if (!$cut) { + $length = $ellipsisLength + ($this->indexOf([' ', "\r", "\n", "\t"], ($length ?: 1) - 1) ?? $stringLength); + } + $str = $this->slice(0, $length - $ellipsisLength); return $ellipsisLength ? $str->trimEnd()->append($ellipsis) : $str; diff --git a/src/Symfony/Component/String/CHANGELOG.md b/src/Symfony/Component/String/CHANGELOG.md index 8c0fbdf4299f..492ad9bd1697 100644 --- a/src/Symfony/Component/String/CHANGELOG.md +++ b/src/Symfony/Component/String/CHANGELOG.md @@ -7,9 +7,10 @@ CHANGELOG * added the `AbstractString::reverse()` method * made `AbstractString::width()` follow POSIX.1-2001 * added `LazyString` which provides memoizing stringable objects - * The component is not marked as `@experimental` anymore. - * Added the `s()` helper method to get either an `UnicodeString` or `ByteString` instance, - depending of the input string UTF-8 compliancy. + * The component is not marked as `@experimental` anymore + * added the `s()` helper method to get either an `UnicodeString` or `ByteString` instance, + depending of the input string UTF-8 compliancy + * added `$cut` parameter to `Symfony\Component\String\AbstractString::truncate()` 5.0.0 ----- diff --git a/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php b/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php index 310f70f986c7..bfc9b1f29b72 100644 --- a/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php +++ b/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php @@ -1405,9 +1405,9 @@ public static function providePadStart() /** * @dataProvider provideTruncate */ - public function testTruncate(string $expected, string $origin, int $length, string $ellipsis) + public function testTruncate(string $expected, string $origin, int $length, string $ellipsis, bool $cut = true) { - $instance = static::createFromString($origin)->truncate($length, $ellipsis); + $instance = static::createFromString($origin)->truncate($length, $ellipsis, $cut); $this->assertEquals(static::createFromString($expected), $instance); } @@ -1417,12 +1417,17 @@ public static function provideTruncate() return [ ['', '', 3, ''], ['', 'foo', 0, '...'], + ['foo', 'foo', 0, '...', false], ['fo', 'foobar', 2, ''], ['foobar', 'foobar', 10, ''], + ['foobar', 'foobar', 10, '...', false], ['foo', 'foo', 3, '...'], ['fo', 'foobar', 2, '...'], ['...', 'foobar', 3, '...'], ['fo...', 'foobar', 5, '...'], + ['foobar...', 'foobar foo', 6, '...', false], + ['foobar...', 'foobar foo', 7, '...', false], + ['foobar foo...', 'foobar foo a', 10, '...', false], ]; }