Skip to content

Commit 76bf2c2

Browse files
committed
[String] Add WORD_STRICT mode to truncate method
1 parent 9f77ba3 commit 76bf2c2

File tree

4 files changed

+75
-4
lines changed

4 files changed

+75
-4
lines changed

src/Symfony/Component/String/AbstractString.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,8 +605,12 @@ public function trimSuffix($suffix): static
605605
return $str;
606606
}
607607

608-
public function truncate(int $length, string $ellipsis = '', bool $cut = true): static
608+
public function truncate(int $length, string $ellipsis = '', bool|TruncateMode $cut = TruncateMode::Char): static
609609
{
610+
if (\is_bool($cut)) {
611+
$cut = $cut ? TruncateMode::Char : TruncateMode::WordAfter;
612+
}
613+
610614
$stringLength = $this->length();
611615

612616
if ($stringLength <= $length) {
@@ -619,7 +623,8 @@ public function truncate(int $length, string $ellipsis = '', bool $cut = true):
619623
$ellipsisLength = 0;
620624
}
621625

622-
if (!$cut) {
626+
$desiredLength = $length;
627+
if (TruncateMode::WordAfter === $cut || TruncateMode::WordBefore === $cut) {
623628
if (null === $length = $this->indexOf([' ', "\r", "\n", "\t"], ($length ?: 1) - 1)) {
624629
return clone $this;
625630
}
@@ -629,6 +634,14 @@ public function truncate(int $length, string $ellipsis = '', bool $cut = true):
629634

630635
$str = $this->slice(0, $length - $ellipsisLength);
631636

637+
if (TruncateMode::WordBefore === $cut) {
638+
if (0 === $ellipsisLength && $desiredLength === $this->indexOf([' ', "\r", "\n", "\t"], $length)) {
639+
return $str;
640+
}
641+
642+
$str = $str->beforeLast([' ', "\r", "\n", "\t"]);
643+
}
644+
632645
return $ellipsisLength ? $str->trimEnd()->append($ellipsis) : $str;
633646
}
634647

src/Symfony/Component/String/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
7.2
5+
---
6+
7+
* Add `TruncateMode::WordBefore` mode to truncate method
8+
49
7.1
510
---
611

src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\String\ByteString;
1717
use Symfony\Component\String\CodePointString;
1818
use Symfony\Component\String\Exception\InvalidArgumentException;
19+
use Symfony\Component\String\TruncateMode;
1920
use Symfony\Component\String\UnicodeString;
2021

2122
abstract class AbstractAsciiTestCase extends TestCase
@@ -1498,22 +1499,24 @@ public static function providePadStart()
14981499
/**
14991500
* @dataProvider provideTruncate
15001501
*/
1501-
public function testTruncate(string $expected, string $origin, int $length, string $ellipsis, bool $cut = true)
1502+
public function testTruncate(string $expected, string $origin, int $length, string $ellipsis, bool|TruncateMode $cut = TruncateMode::Char)
15021503
{
15031504
$instance = static::createFromString($origin)->truncate($length, $ellipsis, $cut);
15041505

15051506
$this->assertEquals(static::createFromString($expected), $instance);
15061507
}
15071508

1508-
public static function provideTruncate()
1509+
public static function provideTruncate(): array
15091510
{
15101511
return [
15111512
['', '', 3, ''],
15121513
['', 'foo', 0, '...'],
15131514
['foo', 'foo', 0, '...', false],
1515+
['foo', 'foo', 0, '...', TruncateMode::WordAfter],
15141516
['fo', 'foobar', 2, ''],
15151517
['foobar', 'foobar', 10, ''],
15161518
['foobar', 'foobar', 10, '...', false],
1519+
['foobar', 'foobar', 10, '...', TruncateMode::WordAfter],
15171520
['foo', 'foo', 3, '...'],
15181521
['fo', 'foobar', 2, '...'],
15191522
['...', 'foobar', 3, '...'],
@@ -1522,6 +1525,14 @@ public static function provideTruncate()
15221525
['foobar...', 'foobar foo', 7, '...', false],
15231526
['foobar foo...', 'foobar foo a', 10, '...', false],
15241527
['foobar foo aar', 'foobar foo aar', 12, '...', false],
1528+
['foobar...', 'foobar foo', 6, '...', TruncateMode::WordAfter],
1529+
['foobar...', 'foobar foo', 7, '...', TruncateMode::WordAfter],
1530+
['foobar foo...', 'foobar foo a', 10, '...', TruncateMode::WordAfter],
1531+
['foobar foo aar', 'foobar foo aar', 12, '...', TruncateMode::WordAfter],
1532+
['foobar foo', 'foobar foo aar', 10, '', TruncateMode::WordBefore],
1533+
['foobar...', 'foobar foo aar', 10, '...', TruncateMode::WordBefore],
1534+
['Lorem ipsum', 'Lorem ipsum dolor sit amet', 14, '', TruncateMode::WordBefore],
1535+
['Lorem...', 'Lorem ipsum dolor sit amet', 10, '...', TruncateMode::WordBefore],
15251536
];
15261537
}
15271538

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\String;
13+
14+
enum TruncateMode
15+
{
16+
/**
17+
* Will cut exactly at given length.
18+
*
19+
* Length: 14
20+
* Source: Lorem ipsum dolor sit amet
21+
* Output: Lorem ipsum do
22+
*/
23+
case Char;
24+
25+
/**
26+
* Returns the string up to the last complete word containing the specified length.
27+
*
28+
* Length: 14
29+
* Source: Lorem ipsum dolor sit amet
30+
* Output: Lorem ipsum
31+
*/
32+
case WordBefore;
33+
34+
/**
35+
* Returns the string up to the complete word after or at the given length.
36+
*
37+
* Length: 14
38+
* Source: Lorem ipsum dolor sit amet
39+
* Output: Lorem ipsum dolor
40+
*/
41+
case WordAfter;
42+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy