#8 alay 插件源码
class FormatContent
{
public function __invoke($serializer, $model, $attributes)
{
if (isset($attributes["contentHtml"])) {
$newHTML = $attributes["contentHtml"];
// 检查 HTML 内容是否为空
if (!is_null($newHTML)) {
// 使用正则表达式匹配所有的链接
$newHTML = preg_replace_callback(
'/<a\s+(?:[^>]*?\s+)?href=["\']([^"\']+)["\']([^>]*)>(.*?)<\/a>/is',
function ($matches) {
$url = $matches[1]; // 获取链接的 href 值
$attributes = $matches[2]; // 获取链接的其他属性
$text = $matches[3]; // 获取链接的文本
// 判断是否为站内链接或内部链接
if ($this->isExternalLink($url)) {
// 对非站内链接添加跳转提示
$redirectUrl = '/goto/' . urlencode($url);
return "<a href=\"{$redirectUrl}\" {$attributes} target=\"_blank\" rel=\"noopener noreferrer\">{$text}</a>";
}
// 保持原样处理站内链接
return $matches[0];
},
$newHTML
);
}
$attributes['contentHtml'] = $newHTML;
}
return $attributes;
}
/**
* 检查是否为外部链接
*
* @param string $url
* @return bool
*/
private function isExternalLink($url)
{
// 获取当前请求的主机名
$currentHost = isset($_SERVER['HTTP_HOST']) ? rtrim($_SERVER['HTTP_HOST'], '/') : '';
// 获取目标 URL 的主机名
$urlHost = parse_url($url, PHP_URL_HOST);
// 如果目标 URL 没有主机名,或者是相对路径,认为是内部链接
if (!$urlHost) {
return false;
}
// 标准化主机名
$currentHost = strtolower($currentHost);
$urlHost = strtolower($urlHost);
// 检查是否为同一主机
return $currentHost !== $urlHost;
}
}
在 extend.php
里边Inject一下
(new Extend\ApiSerializer(PostSerializer::class))
->attributes(FormatContent::class),
(new Extend\ApiSerializer(BasicPostSerializer::class))
->attributes(FormatContent::class),