Files
laralog/app/Support/helpers.php
T
ak 8f1ff6e3f9 feat: 外链中转 /go——点击统计 + 拦截 + 隐藏真实链接
- redirects 表 + UrlRedirector:go_url() 站外链接改写为 /go/{hash}(确定性 hash、同 URL 复用、并发安全、缓存)
- /go/{hash} 302 跳转 + 点击计数 + 最后点击时间;停用状态 410(二次拦截);后台「外链中转」资源可查看点击量/启停/删除
- 接入点:正文外链(渲染器统一改写)、评论正文自动链接(comment_body)、评论作者网址、友链(侧边栏+友链页);站内/相对/mailto/tel/锚点不中转
- 测试 6 个(改写/计数/拦截/复用/渲染/评论正文);README 补充
2026-08-13 01:28:10 +08:00

73 lines
2.0 KiB
PHP

<?php
declare(strict_types=1);
use App\Blog\Support\ThemeManager;
if (! function_exists('theme_view')) {
/**
* 渲染主题视图:激活主题目录已前置到全局视图路径,主题缺失时自动回退默认视图。
*/
function theme_view(string $view, array $data = []): \Illuminate\Contracts\View\View
{
return view($view, $data);
}
}
if (! function_exists('theme')) {
/**
* 主题辅助函数:theme() / theme('asset', 'style.css') / theme('var', 'key', default)
*/
function theme(?string $method = null, ...$args): mixed
{
$manager = app(ThemeManager::class);
return match ($method) {
'asset' => $manager->assetUrl($args[0] ?? '', $args[1] ?? null),
'var' => $manager->variable($args[0] ?? '', $args[1] ?? null),
'vars' => $manager->variables(),
'name' => $manager->active(),
default => $manager,
};
}
}
if (! function_exists('blog_setting')) {
/**
* 读取博客设置(Setting 表,带缓存)。
*/
function blog_setting(string $key, mixed $default = null): mixed
{
return \App\Models\Setting::get($key, $default);
}
}
if (! function_exists('go_url')) {
/**
* 外链中转:站外链接改写为 /go/{hash}(点击统计/拦截),站内链接原样返回。
*/
function go_url(string $url): string
{
return app(\App\Blog\Services\UrlRedirector::class)->goUrl($url);
}
}
if (! function_exists('comment_body')) {
/**
* 评论正文:转义 + 自动链接 URL(走 /go 中转,nofollow)。
*/
function comment_body(string $text): string
{
$text = e($text);
$text = preg_replace_callback(
'#(https?://[^\s<>"\'()]+)#i',
fn (array $m) => '<a href="'.e(go_url($m[1])).'" target="_blank" rel="nofollow noopener">'.$m[1].'</a>',
$text
);
return nl2br($text);
}
}