v3.2.13 图片选项全部自带默认图,新装站点不再出现空洞/破图
根本原因:kratos_option() 运行时只读数据库,`std` 仅在后台表单预填和 「恢复默认」时生效,前台根本读不到。因此新装站点所有图片项都是空值。 另外 isset() 挡不住「用户清空」——of_sanitize_upload() 对空输入返回 '', 键存在且值为空串,调用方传的兜底值被绕过。 同时不能把绝对 URL 写进 std:它会随保存一起写库,主题目录改名/换 CDN/ 迁站后永久 404。本站 s_wechat_url / g_donate_alipay / g_donate_wechat 三项就指向已删除的 kratos-master 目录,一直在破图(这三项是 hidden 字段, 后台界面上看不到,所以坏了很久没人发现)。 做法: - 新增 inc/theme-option-defaults.php,图片默认值注册表(11 项), 默认图一律运行时给出,不写数据库。 - yang_option_image() 三层判断:空/纯空白 → 默认图;指向已不存在的主题 目录 → 默认图;文件不存在则不输出地址(避免换来一个 404)。 - 陈旧判断用 get_template()(主题 slug)而非 basename(目录名),避免本地 开发目录名与 slug 不一致时误伤当前主题自己的图。 - 模板统一走取值函数:header(logo/favicon/banner)、footer(微信码/国旗)、 404、index、article 缩略图、widgets 头像、page-toolbar、theme-core 赞赏码。 - 国旗与 favicon 的渲染抽成 yang_flag_block() / yang_favicon_tag(), 空值时不输出空 src / 空 href。 - 后台 9 处 std 改为 yang_options_default_img(),与前台默认图同源; 该包装函数自带 function_exists 防护,单独加载 theme-options.php 不会 Fatal。 新增图片(本地生成,合计 291KB):default-404 / default-share / default-empty / default-avatar / default-banner / default-flag / favicon.ico。 favicon 为 WordPress 风格自绘(品牌蓝圆底 + 白色 W),非站长个人专用那张。 验证:run_tests 146 条(新增第 4 组图片默认值 22+ 条);falsify 35 条注入 全部能被抓住(新增 10 条);verify_all.sh 14 组全绿。
This commit is contained in:
+51
-12
@@ -20,6 +20,29 @@ function getrobots()
|
||||
return $robots;
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片字段的默认值(后台预填用)。
|
||||
*
|
||||
* ── 为什么不直接调 yang_image_default() ──────────────────────
|
||||
* 本文件由 optionsframework_init() 在 init 钩子上 require,
|
||||
* 而 yang_image_default() 来自 inc/theme-option-defaults.php。
|
||||
* 正常时序下后者先加载,但**加载顺序被打乱时**(子主题、外部脚本
|
||||
* 直接 include 本文件、插件在更早的钩子里触发本函数),
|
||||
* 直接调用就会 Fatal —— 后台整个白屏,比"少一个预填值"严重得多。
|
||||
*
|
||||
* 这里先用 function_exists() 探一下,缺了就返回空串:
|
||||
* 后台退化成没有预填默认值,但页面能打开、能保存、能干活。
|
||||
* 降级必须降到"还能用",不能降到"打不开"。
|
||||
*/
|
||||
if (!function_exists('yang_options_default_img')) {
|
||||
function yang_options_default_img($id)
|
||||
{
|
||||
return function_exists('yang_image_default')
|
||||
? yang_image_default($id)
|
||||
: '';
|
||||
}
|
||||
}
|
||||
|
||||
function kratos_options()
|
||||
{
|
||||
$sitename = get_bloginfo('name');
|
||||
@@ -55,12 +78,24 @@ function kratos_options()
|
||||
'desc' => __('不选择图片则显示文字标题', 'kratos'),
|
||||
'id' => 'g_logo',
|
||||
'type' => 'upload',
|
||||
/* 有意不设 std:这里空着时显示站点名称文字,比塞一张通用占位
|
||||
logo 好看。其它图片字段见 inc/theme-option-defaults.php。 */
|
||||
);
|
||||
|
||||
$options[] = array(
|
||||
'name' => __('Favicon 图片', 'kratos'),
|
||||
'desc' => __('浏览器收藏夹和地址栏中显示的图标', 'kratos'),
|
||||
'desc' => __('浏览器收藏夹和地址栏中显示的图标。<b>留空则自动使用主题自带的默认图标</b>,不会出现空白。', 'kratos'),
|
||||
'id' => 'g_icon',
|
||||
/* 有意不写 std。
|
||||
*
|
||||
* std 里存的是**绝对 URL**,一旦用户保存表单就会被写进数据库。
|
||||
* 数据库里躺着一个写死的主题目录地址是隐患:主题目录改名、
|
||||
* 换 CDN、或站点迁移域名之后,那条记录就指向不存在的文件
|
||||
* (线上 s_wechat_url 指向早已删除的 kratos-master 目录,就是这么坏掉的)。
|
||||
*
|
||||
* 所以默认值一律由运行时提供(yang_option_image()),库里保持空。
|
||||
* 这样默认图地址永远由当前请求现算,改目录也不用改数据。
|
||||
*/
|
||||
'type' => 'upload',
|
||||
);
|
||||
$options[] = array(
|
||||
@@ -72,8 +107,9 @@ $options[] = array(
|
||||
);
|
||||
$options[] = array(
|
||||
'name' => __('国旗地址', 'kratos'),
|
||||
'desc' => __('选择国旗图片地址', 'kratos'),
|
||||
'desc' => __('选择国旗图片地址。<b>留空则自动使用主题自带的默认国旗</b>。', 'kratos'),
|
||||
'id' => 'g_flag_url',
|
||||
/* 不写 std —— 理由同 g_icon:默认值由运行时给,库里不存绝对地址。 */
|
||||
'type' => 'upload',
|
||||
);
|
||||
$options[] = array(
|
||||
@@ -158,16 +194,19 @@ $options[] = array(
|
||||
|
||||
$options[] = array(
|
||||
'id' => 's_wechat_url',
|
||||
'std' => ASSET_PATH . '/assets/img/wechat.png',
|
||||
/* 后台显示的初始值必须与前台实际用的默认图**同一份来源**,
|
||||
否则用户在后台看到 A 图、前台显示 B 图,一保存又把 A 写进库,
|
||||
前台跟着退回 A —— 前后台像两个产品。
|
||||
所以这里统一从 yang_image_defaults() 取,不在两处各写一遍路径。 */
|
||||
'std' => yang_options_default_img('s_wechat_url'),
|
||||
'type' => 'upload',
|
||||
'class' => 'hidden',
|
||||
'type' => 'upload',
|
||||
);
|
||||
|
||||
$options[] = array(
|
||||
'name' => __('404 页面图片', 'kratos'),
|
||||
'id' => 'g_404',
|
||||
'std' => ASSET_PATH . '/assets/img/404.jpg',
|
||||
'std' => yang_options_default_img('g_404'),
|
||||
'type' => 'upload',
|
||||
);
|
||||
|
||||
@@ -180,7 +219,7 @@ $options[] = array(
|
||||
'name' => __('分享图片', 'kratos'),
|
||||
'desc' => __('搜索引擎或者社交工具分享首页时抓取的图片', 'kratos'),
|
||||
'id' => 'seo_shareimg',
|
||||
'std' => ASSET_PATH . '/assets/img/default.jpg',
|
||||
'std' => yang_options_default_img('seo_shareimg'),
|
||||
'type' => 'upload',
|
||||
);
|
||||
|
||||
@@ -314,7 +353,7 @@ $options[] = array(
|
||||
'desc' => __('当文章中没有图片并且没有设置特色图时在首页显示', 'kratos'),
|
||||
'id' => 'g_postthumbnail',
|
||||
'class' => 'hidden',
|
||||
'std' => ASSET_PATH . '/assets/img/default.jpg',
|
||||
'std' => yang_options_default_img('g_postthumbnail'),
|
||||
'type' => 'upload',
|
||||
);
|
||||
|
||||
@@ -322,7 +361,7 @@ $options[] = array(
|
||||
'name' => __('无内容图片', 'kratos'),
|
||||
'desc' => __('当搜索不到文章或文章分类中没有文章时显示', 'kratos'),
|
||||
'id' => 'g_nothing',
|
||||
'std' => ASSET_PATH . '/assets/img/nothing.svg',
|
||||
'std' => yang_options_default_img('g_nothing'),
|
||||
'type' => 'upload',
|
||||
);
|
||||
|
||||
@@ -342,7 +381,7 @@ $options[] = array(
|
||||
$options[] = array(
|
||||
'name' => __('支付宝二维码', 'kratos'),
|
||||
'id' => 'g_donate_alipay',
|
||||
'std' => ASSET_PATH . '/assets/img/donate.png',
|
||||
'std' => yang_options_default_img('g_donate_alipay'),
|
||||
'type' => 'upload',
|
||||
'class' => 'hidden',
|
||||
'type' => 'upload',
|
||||
@@ -351,7 +390,7 @@ $options[] = array(
|
||||
$options[] = array(
|
||||
'name' => __('微信二维码', 'kratos'),
|
||||
'id' => 'g_donate_wechat',
|
||||
'std' => ASSET_PATH . '/assets/img/donate.png',
|
||||
'std' => yang_options_default_img('g_donate_wechat'),
|
||||
'type' => 'upload',
|
||||
'class' => 'hidden',
|
||||
'type' => 'upload',
|
||||
@@ -376,7 +415,7 @@ $options[] = array(
|
||||
$options[] = array(
|
||||
'name' => __('个人头像', 'kratos'),
|
||||
'id' => 'a_gravatar',
|
||||
'std' => ASSET_PATH . '/assets/img/gravatar.png',
|
||||
'std' => yang_options_default_img('a_gravatar'),
|
||||
'type' => 'upload',
|
||||
);
|
||||
|
||||
@@ -477,7 +516,7 @@ $options[] = array(
|
||||
$options[] = array(
|
||||
'name' => __('图片导航', 'kratos'),
|
||||
'id' => 'top_img',
|
||||
'std' => ASSET_PATH . '/assets/img/background.png',
|
||||
'std' => yang_options_default_img('top_img'),
|
||||
'class' => 'hidden',
|
||||
'type' => 'upload',
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user