Skip to content

Commit

Permalink
Improve URL formatting with more flexible truncation (#1032)
Browse files Browse the repository at this point in the history
  • Loading branch information
realodix authored Dec 12, 2024
1 parent e34be16 commit e78adf4
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 19 deletions.
44 changes: 29 additions & 15 deletions app/Helpers/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
27 changes: 23 additions & 4 deletions tests/Unit/Helpers/HelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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),
);
}

Expand Down

0 comments on commit e78adf4

Please sign in to comment.