后台上传站点图标:首页品牌图 + favicon + PWA 图标一起换
需求:后台新增设置,允许管理员上传自己的图标;上传后首页品牌图标与浏览器 标签页 favicon(以及「添加到手机主屏」图标)一起换成它。 要点: - 一张上传图服务端居中裁剪成正方形,生成 16/32/48/64/180/192/512 + maskable 192/512 整套尺寸,并手工拼装多帧 favicon.ico。 - 单一来源 site_icon_url() 统一取址;site_icon_head() 被首页/登录页/后台 三处共用;PWA manifest 改由 manifest.php 动态输出、maskable 也跟随 —— 三处防线共同杜绝「首页换了、标签页还是旧的」这类半生效。 - 目录可写则落静态文件(最快);不可写的保守环境整套压进设置、由 site-icon.php 按需输出,功能不因权限限制整块不可用。 - 与「网站列表里每个网站自己的图标」是两个维度:目录与设置键都分开, 清理时互不误伤。 顺手修掉两个真问题: - login.php / admin/_auth.php 各留了一行写死的 favicon,与新的 site_icon_head() 并存 → head 里两条 rel="icon",是「上传了却没换」的 温床。已删掉写死那两行。 - 自定义 favicon.ico 原先只塞 16+32 两帧,而内置是 16/32/48/64 四帧 —— 换图标反而退步。已补齐 icon-64 并统一为 4 帧。 - setting() 的请求内缓存导致「同请求写后再读」拿到旧值(真实坑): settings_cache() 支持强制重载 + settings_reload(),写入后立即失效。 验证:单测 44/44(含只读目录动态回退)、HTTP 56/56、e2e 174/0、 反向验证 5 变体全部被抓住(含「写死残留」与「ico 只塞两帧」两个新哨兵)、 真机几何 360/390/768/1440 无溢出、线上直连桌面+移动端几何全绿、 线上诊断页走通「上传→前台全换→复原」。
This commit is contained in:
@@ -207,6 +207,58 @@ try {
|
||||
break;
|
||||
}
|
||||
|
||||
/* ---------- 站点整体图标(favicon + 首页品牌图标) ---------- */
|
||||
case 'site_icon_save': {
|
||||
$back = 'admin/?p=settings';
|
||||
$f = $_FILES['site_icon_file'] ?? null;
|
||||
if (!$f || empty($f['tmp_name']) || !is_uploaded_file((string)$f['tmp_name'])) {
|
||||
flash('请选择要上传的图片', 'err');
|
||||
break;
|
||||
}
|
||||
if ((int)$f['error'] !== UPLOAD_ERR_OK) {
|
||||
flash('上传失败(错误码 ' . (int)$f['error'] . ',可能是文件超过服务器上限)', 'err');
|
||||
break;
|
||||
}
|
||||
$size = (int)($f['size'] ?? 0);
|
||||
if ($size <= 0) {
|
||||
flash('上传的文件是空的', 'err');
|
||||
break;
|
||||
}
|
||||
if ($size > 5 * 1024 * 1024) {
|
||||
flash('图片太大了(' . round($size / 1048576, 1) . 'MB),请压缩到 5MB 以内', 'err');
|
||||
break;
|
||||
}
|
||||
$bin = (string)@file_get_contents((string)$f['tmp_name']);
|
||||
if ($bin === '') {
|
||||
flash('读取上传文件失败', 'err');
|
||||
break;
|
||||
}
|
||||
// 只认图片:SVG 不收(矢量图当站点图标会带来 XSS 面,且栅格化各端不一致)
|
||||
$im = gd_load($bin);
|
||||
if ($im === null) {
|
||||
flash('这不是一张能识别的图片(支持 PNG / JPG / GIF / WebP)', 'err');
|
||||
break;
|
||||
}
|
||||
$iw = imagesx($im);
|
||||
$ih = imagesy($im);
|
||||
imagedestroy($im);
|
||||
|
||||
$err = save_site_logo($bin);
|
||||
if ($err !== '') {
|
||||
flash($err, 'err');
|
||||
} else {
|
||||
flash('站点图标已更新(' . $iw . '×' . $ih
|
||||
. ' → 已生成 favicon 与手机主屏图标等一整套尺寸)');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'site_icon_reset': {
|
||||
$back = 'admin/?p=settings';
|
||||
reset_site_logo();
|
||||
flash('已恢复默认图标');
|
||||
break;
|
||||
}
|
||||
|
||||
/* ---------- 设置 ---------- */
|
||||
case 'settings_save': {
|
||||
$srcRaw = (string)($_POST['suggest_source'] ?? 'baidu');
|
||||
|
||||
Reference in New Issue
Block a user