diff --git a/app/Helpers/Helper.php b/app/Helpers/Helper.php index 799d93de7..e91ce56aa 100644 --- a/app/Helpers/Helper.php +++ b/app/Helpers/Helper.php @@ -21,38 +21,52 @@ public static function deviceDetector() } /** - * A URL formatted according to the specified format. + * Format URL links for display. * * @param string $value URL links * @param int|null $limit Length string will be truncated to, including suffix * @param bool $scheme Show or remove URL schemes * @param bool $trailingSlash Show or remove trailing slash + * @param int $maxHostLength Maximum length of the host * @return string */ - public static function urlFormat(string $value, ?int $limit = null, bool $scheme = true, bool $trailingSlash = true) - { + public static function urlFormat( + string $value, + ?int $limit = null, + bool $scheme = true, + bool $trailingSlash = true, + int $maxHostLength = 45, + ) { $uri = \Illuminate\Support\Uri::of($value); - $hostLen = strlen($uri->scheme() . '://' . $uri->host()); - $limit ??= strlen($value); + $schemePrefix = $scheme && $uri->scheme() ? $uri->scheme() . '://' : ''; - // Optionally strip scheme - if ($scheme === false) { - $value = Preg::replace('{^http(s)?://}', '', $value); - $hostLen = strlen($uri->host()); + // Strip scheme if not required + if (!$scheme) { + $value = Preg::replace('/^https?:\/\//', '', $value); } - // Optionally strip trailing slash - if ($trailingSlash === false) { + // Remove trailing slash if not required + if (!$trailingSlash) { $value = rtrim($value, '/'); } + $limit = $limit ?? strlen($value); + $hostLength = strlen($schemePrefix . $uri->host()); + + // Truncate the URL if necessary if (strlen($value) > $limit) { $trimMarker = '...'; - $pathLen = $limit - $hostLen; - $firstPartLen = $hostLen + intval(($pathLen - 1) * 0.5) + strlen($trimMarker); - $lastPartLen = -abs($limit - $firstPartLen); + $adjustedLimit = $limit - strlen($trimMarker); + + // Handle cases where host is too long or the limit is shorter than the host + if ($hostLength >= $maxHostLength || $hostLength >= $adjustedLimit) { + $firstHalf = mb_substr($value, 0, intval($adjustedLimit * 0.8)); + $secondHalf = mb_substr($value, -intval($adjustedLimit * 0.2)); + + return $firstHalf . $trimMarker . $secondHalf; + } - return mb_strimwidth($value, 0, $firstPartLen, $trimMarker) . substr($value, $lastPartLen); + return \Illuminate\Support\Str::limit($value, $limit, $trimMarker); } return $value; diff --git a/tests/Unit/Helpers/HelperTest.php b/tests/Unit/Helpers/HelperTest.php index 1bc6e30ad..93588b906 100644 --- a/tests/Unit/Helpers/HelperTest.php +++ b/tests/Unit/Helpers/HelperTest.php @@ -25,18 +25,37 @@ public function urlFormat(): void $url = 'https://github.com/laravel/framework/commit/de69bb287c5017d1acb7d47a6db1dedf578036d6'; $this->assertSame( - 'https://github.com/lara...36d6', + 'https://github.com/laravel/fra...', Helper::urlFormat($url, limit: 30), ); $this->assertSame( - 'github.com/laravel/...578036d6', + 'github.com/laravel/framework/c...', Helper::urlFormat($url, scheme: false, limit: 30), ); + } + + /** + * Test the urlFormat() method with too long host. + */ + #[PHPUnit\Test] + public function urlFormatWithTooLongHost(): void + { + $url = 'http://theofficialabsolutelongestdomainnameregisteredontheworldwideweb.international/search?client=firefox-b-d&q=longets+domain'; + + $this->assertSame( + 'http://theofficialabsolutelongestdomainnameregisteredontheworldwidewe...&q=longets+domain', + Helper::urlFormat($url, limit: 90), + ); + + $this->assertSame( + 'theofficialabsolutelongestdomainnameregisteredontheworldwideweb....q=longets+domain', + Helper::urlFormat($url, scheme: false, limit: 84), + ); $this->assertSame( - 'github.com/laravel/...8036d6/', - Helper::urlFormat($url . '/', scheme: false, limit: 29), + 'https://hunterxhunter...unter', + Helper::urlFormat('https://hunterxhunter.fandom.com/wiki/Hunter_%C3%97_Hunter', limit: 30), ); }