This commit is contained in:
2025-05-12 14:25:25 +02:00
parent ab2db755ef
commit 9e378ca2b7
2719 changed files with 46505 additions and 60181 deletions

View File

@@ -263,7 +263,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
public function endsWith(string|iterable $suffix): bool
{
if (\is_string($suffix)) {
throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
}
foreach ($suffix as $s) {
@@ -312,7 +312,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
public function equalsTo(string|iterable $string): bool
{
if (\is_string($string)) {
throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
}
foreach ($string as $s) {
@@ -340,7 +340,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
public function indexOf(string|iterable $needle, int $offset = 0): ?int
{
if (\is_string($needle)) {
throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
}
$i = \PHP_INT_MAX;
@@ -362,7 +362,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
public function indexOfLast(string|iterable $needle, int $offset = 0): ?int
{
if (\is_string($needle)) {
throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
}
$i = null;
@@ -383,7 +383,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
return '' === $this->string;
}
abstract public function join(array $strings, string $lastGlue = null): static;
abstract public function join(array $strings, ?string $lastGlue = null): static;
public function jsonSerialize(): string
{
@@ -414,7 +414,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
public function repeat(int $multiplier): static
{
if (0 > $multiplier) {
throw new InvalidArgumentException(sprintf('Multiplier must be positive, %d given.', $multiplier));
throw new InvalidArgumentException(\sprintf('Multiplier must be positive, %d given.', $multiplier));
}
$str = clone $this;
@@ -429,16 +429,21 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
abstract public function reverse(): static;
abstract public function slice(int $start = 0, int $length = null): static;
abstract public function slice(int $start = 0, ?int $length = null): static;
abstract public function snake(): static;
abstract public function splice(string $replacement, int $start = 0, int $length = null): static;
public function kebab(): static
{
return $this->snake()->replace('_', '-');
}
abstract public function splice(string $replacement, int $start = 0, ?int $length = null): static;
/**
* @return static[]
*/
public function split(string $delimiter, int $limit = null, int $flags = null): array
public function split(string $delimiter, ?int $limit = null, ?int $flags = null): array
{
if (null === $flags) {
throw new \TypeError('Split behavior when $flags is null must be implemented by child classes.');
@@ -481,7 +486,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
public function startsWith(string|iterable $prefix): bool
{
if (\is_string($prefix)) {
throw new \TypeError(sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
}
foreach ($prefix as $prefix) {
@@ -495,7 +500,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
abstract public function title(bool $allWords = false): static;
public function toByteString(string $toEncoding = null): ByteString
public function toByteString(?string $toEncoding = null): ByteString
{
$b = new ByteString();
@@ -605,7 +610,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
return $str;
}
public function truncate(int $length, string $ellipsis = '', bool $cut = true): static
public function truncate(int $length, string $ellipsis = '', bool|TruncateMode $cut = TruncateMode::Char): static
{
$stringLength = $this->length();
@@ -619,16 +624,27 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
$ellipsisLength = 0;
}
if (!$cut) {
$desiredLength = $length;
if (TruncateMode::WordAfter === $cut || !$cut) {
if (null === $length = $this->indexOf([' ', "\r", "\n", "\t"], ($length ?: 1) - 1)) {
return clone $this;
}
$length += $ellipsisLength;
} elseif (TruncateMode::WordBefore === $cut && null !== $this->indexOf([' ', "\r", "\n", "\t"], ($length ?: 1) - 1)) {
$length += $ellipsisLength;
}
$str = $this->slice(0, $length - $ellipsisLength);
if (TruncateMode::WordBefore === $cut) {
if (0 === $ellipsisLength && $desiredLength === $this->indexOf([' ', "\r", "\n", "\t"], $length)) {
return $str;
}
$str = $str->beforeLast([' ', "\r", "\n", "\t"]);
}
return $ellipsisLength ? $str->trimEnd()->append($ellipsis) : $str;
}