Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions plugins/baser-core/src/View/Helper/BcTextHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -475,4 +475,55 @@ public function booleanStatus($value)
}
// <<<

/**
* テキスト内のURLを自動でリンク化
*
* CakePHP本体の autoLinkUrls() では、ドメインのみURLの末尾スラッシュが
* リンク外に出るケースがあるため、リンク直後のスラッシュだけ補正する。
*
* @param string $text テキスト
* @param array<string, mixed> $options リンクオプション
* @return string リンク化後テキスト
* @checked
* @noTodo
* @unitTest
*/
public function autoLinkUrls(string $text, array $options = []): string
{
$linkedText = parent::autoLinkUrls($text, $options);

return $this->fixTrailingSlashOutsideAnchor($linkedText);
}

/**
* ドメインのみURLで末尾スラッシュがリンク外に出る表示崩れを補正
*
* @param string $text リンク化後テキスト
* @return string 補正後テキスト
*/
protected function fixTrailingSlashOutsideAnchor(string $text): string
{
// 壊れたパターンだけを対象に補正する。
// 例: <a href="https://example.com">https://example.com</a>/
//
// (?<before>) : href 属性より前の属性群(class, target など)
// (?<href>) : href 値(スキーム + ドメインのみ。末尾スラッシュなし)
// (?<after>) : href 属性より後の属性群
// (?<label>) : リンク表示文字列(スキーム + ドメインのみ)
//
// 末尾の / は </a> の外側にあるものだけを拾い、直後が空白・タグ開始・行末の場合に限定する。
// パス付きURLや通常のリンクには触れず、副作用を避ける。
$result = preg_replace_callback(
'/<a\\b(?<before>[^>]*?)href="(?<href>(?:https?|ftp|nntp):\\/\\/[^"\\/\\s<]+)"(?<after>[^>]*)>(?<label>(?:https?|ftp|nntp):\\/\\/[^"\\/\\s<]+)<\\/a>\\/(?=[\\s<]|$)/u',
static function (array $matches): string {
$href = $matches['href'] . '/';
$label = $matches['label'] . '/';

return '<a' . $matches['before'] . 'href="' . $href . '"' . $matches['after'] . '>' . $label . '</a>';
},
$text
);

return $result ?? $text;
}
}
18 changes: 18 additions & 0 deletions plugins/baser-core/tests/TestCase/View/Helper/BcTextHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -488,4 +488,22 @@ public function testBooleanStatus()

}

/**
* autoLinkUrls の末尾スラッシュ補正のテスト
*/
public function testAutoLinkUrlsTrailingSlash()
{
$result = $this->Helper->autoLinkUrls('https://example.com/');
$this->assertMatchesRegularExpression('/href=[\'\"]https:\/\/example\\.com\/[\'\"]/', $result);
$this->assertStringContainsString('>https://example.com/</a>', $result);
$this->assertStringNotContainsString('</a>/', $result);

$resultWithPath = $this->Helper->autoLinkUrls('https://example.com/path/');
$this->assertStringContainsString('>https://example.com/path/</a>', $resultWithPath);

$resultWithText = $this->Helper->autoLinkUrls('URL: https://example.com/ end');
$this->assertStringContainsString('>https://example.com/</a> end', $resultWithText);
$this->assertStringNotContainsString('</a>/ end', $resultWithText);
}

}
Loading