fix(admin): replicate reference front-submit settings page 1:1

- Rewrite post_list/submit schema (PHP + JS) with the reference theme's
  field set, order, defaults and dependencies; topics fields excluded
- Map PostDisplay::get_submit_settings() and the FrontSubmit runtime to
  the new keys without legacy fallback
- Guest submission follows the capability matrix; category required on
  submit; pay limits read from the cash/points fieldset
- Drop dead front_submit_* settings, template branches and JS config
- Add submit settings reference contract test
This commit is contained in:
2026-09-24 12:29:19 +08:00
parent ed71314986
commit 264f2c51b2
14 changed files with 354 additions and 292 deletions
@@ -2,123 +2,85 @@ export const submitSchema = {
key: 'post_list.submit',
title: '前台投稿',
icon: 'fa fas fa-paper-plane',
description: '配置前台投稿表单字段、审核流程、附件权限和封面策略。',
description: '配置前台投稿的开关、可选分类、免登录发布用户、标题与付费限制。',
defaults: {
front_submit_enabled: true,
front_submit_roles: 'author,editor,administrator',
front_submit_title: true,
front_submit_content: true,
front_submit_excerpt: true,
front_submit_cover: true,
front_submit_category: true,
post_article_cat: [],
front_submit_tags: true,
post_article_custom_filter_s: true,
front_submit_custom_fields: '',
front_submit_review_mode: 'pending',
front_submit_cover_required: false,
front_submit_max_images: 5,
front_submit_editor_mode: 'rich',
front_submit_draft_save: true,
front_submit_leave_warning: true,
front_submit_guest_enabled: false,
post_article_s: true,
post_article_btn_txte: '发布文章',
post_article_title_strlen_limit_min: 5,
post_article_title_strlen_limit_max: 30,
post_article_user: 0,
post_article_cat: [],
post_article_custom_filter_s: true,
post_article_tag: true,
post_article_user: 1,
post_article_title_strlen_limit: { min: 5, max: 30 },
post_article_pay_free_s: true,
post_article_pay_price_min: '0.00',
post_article_pay_price_max: '100.00',
post_article_pay_price_limit: { price: { min: 0, max: 99999 }, points: { min: 0, max: 0 } },
post_article_pay_vip_price_s: true,
post_article_pay_vip_1_discount: 80,
post_article_pay_vip_2_discount: 50,
post_article_pay_vip_1_discount: 100,
post_article_pay_vip_2_discount: 100,
post_t_placeholder: '请输入标题',
post_c_placeholder: '请输入内容',
},
groups: [
{
key: 'basic',
title: '基础配置',
icon: 'fa fas fa-cog',
key: 'submit',
title: '',
fields: [
{ key: 'front_submit_enabled', label: '开启前台投稿', type: 'switch', default: true, help: '允许用户在前台提交文章' },
{ key: 'front_submit_roles', label: '允许投稿的角色', type: 'input', default: 'author,editor,administrator', dependsOn: { key: 'front_submit_enabled', value: true }, help: '逗号分隔角色标识' },
{ key: 'post_article_btn_txte', label: '投稿按钮文案', type: 'input', default: '发布文章', dependsOn: { key: 'front_submit_enabled', value: true }, help: '前台投稿按钮显示的文字' },
{ key: 'post_article_title_strlen_limit_min', label: '标题最少字数', type: 'number', default: 5, min: 1, max: 100, dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'post_article_title_strlen_limit_max', label: '标题最多字数', type: 'number', default: 30, min: 5, max: 200, dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'post_t_placeholder', label: '标题占位符', type: 'input', default: '', placeholder: '请输入标题', dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'post_c_placeholder', label: '内容占位符', type: 'textarea', default: '', placeholder: '请输入内容', dependsOn: { key: 'front_submit_enabled', value: true } },
],
},
{ key: 'post_article_s', label: '启用前台投稿', type: 'switch', default: true },
{
key: 'fields',
title: '表单字段',
icon: 'fa fas fa-list-alt',
key: 'submit_perm_notice',
label: '',
type: 'content',
ui_only: true,
content: '<p style="margin:0;font-size:12px;color:var(--aksrt-color-muted);line-height:1.6;">此功能启用后,可以在<a href="admin.php?page=aksrt-settings#/permissions/capabilities">权限管理</a>中设置用户的发布、审核权限 <a href="admin.php?page=aksrt-settings#/permissions/capabilities">【去设置】</a></p>',
},
{ key: 'post_article_btn_txte', label: '按钮文字', type: 'input', default: '发布文章', dependsOn: { key: 'post_article_s', value: true }, description: '投稿按钮的显示的文字,推荐4个字更加协调' },
{ key: 'post_article_cat', label: '投稿允许选择的分类', type: 'taxonomy_select', taxonomy: 'category', multiple: true, default: [], placeholder: '输入关键词以搜索分类', dependsOn: { key: 'post_article_s', value: true }, description: '投稿允许选择的分类,为空则允许选择全部分类,所选分类下如果有子分类则会自动显示,如果选择了上级分类,则不要再选该分类下的子分类。注意:请确保所选分类包含子分类总数不要超过50个,否则可能会引起页面崩溃' },
{ key: 'post_article_custom_filter_s', label: '允许选择高级筛选', type: 'switch', default: true, dependsOn: { key: 'post_article_s', value: true } },
{
key: 'submit_filter_notice',
label: '',
type: 'content',
ui_only: true,
content: '<p style="margin:0;font-size:12px;color:var(--aksrt-color-muted);line-height:1.6;">此功能启用后,请先在<a href="admin.php?page=aksrt-settings#/post-list/filter">文章列表/高级筛选</a>中添加高级筛选明细 <a href="admin.php?page=aksrt-settings#/post-list/filter">【去设置】</a></p>',
},
{ key: 'post_article_tag', label: '允许插入标签', type: 'switch', default: true, dependsOn: { key: 'post_article_s', value: true }, description: '前台投稿时候允许设置文章标签' },
{ key: 'post_article_user', label: '免登陆投稿发布用户', type: 'user_select', default: 1, dependsOn: { key: 'post_article_s', value: true }, description: '当选择投稿权限为无需登录就能投稿时,投稿文章的用户' },
{ key: 'post_article_title_strlen_limit', label: '标题字数限制', type: 'between_number', default: { min: 5, max: 30 }, unit: '字', description: '限制标题字数可有效的防止灌水等无意义内容(英文字符按0.5个字计算)' },
{ key: 'post_article_pay_free_s', label: '允许设置为免费资源', type: 'switch', default: true, dependsOn: { key: 'post_article_s', value: true }, description: '付费内容金额允许设置为 0' },
{
key: 'post_article_pay_price_limit',
label: '付费内容金额限制',
type: 'fieldset',
default: { price: { min: 0, max: 99999 }, points: { min: 0, max: 0 } },
description: '限制用户允许设置的金额,防止金额过高不合理(填0为不限制)',
fields: [
{ key: 'front_submit_title', label: '标题', type: 'switch', default: true, dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'front_submit_content', label: '正文', type: 'switch', default: true, dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'front_submit_excerpt', label: '摘要', type: 'switch', default: true, dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'front_submit_cover', label: '封面图', type: 'switch', default: true, dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'front_submit_category', label: '分类选择', type: 'switch', default: true, dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'post_article_cat', label: '允许投稿分类', type: 'taxonomy_select', taxonomy: 'category', multiple: true, default: [], help: '为空则允许全部分类', dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'front_submit_guest_enabled', label: '允许免登录投稿', type: 'switch', default: false, help: '开启后访客可投稿;文章归属到下方用户', dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'post_article_user', label: '免登录归属用户', type: 'user_select', default: 0, help: '免登录投稿时文章归属的用户,搜索选择', dependsOn: { key: 'front_submit_guest_enabled', value: true } },
{ key: 'front_submit_tags', label: '标签输入', type: 'switch', default: true, dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'post_article_custom_filter_s', label: '高级筛选选择', type: 'switch', default: true, help: '投稿时可选择自定义筛选维度值', dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'front_submit_custom_fields', label: '自定义字段', type: 'textarea', default: '', placeholder: '每行一个:field_key|字段名称|类型(input/textarea/select)', dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'price', label: '现金金额限制', type: 'between_number', default: { min: 0, max: 99999 } },
{ key: 'points', label: '积分金额限制', type: 'between_number', default: { min: 0, max: 0 } },
],
},
{ key: 'post_article_pay_vip_price_s', label: '付费内容允许设置会员价', type: 'switch', default: true, dependsOn: { key: 'post_article_s', value: true }, description: '前台投稿时对拥有设置付费内容权限的用户,是否开启设置会员价格。开启此项,会直接在前台显示设置会员价的选项;关闭此项,则用户只能设置普通价格,会员价则按照下方设置的折扣自动计算' },
{
key: 'review',
title: '审核策略',
icon: 'fa fas fa-tasks',
fields: [
{
key: 'front_submit_review_mode',
label: '审核模式',
type: 'radio',
default: 'pending',
options: [
{ label: '待审核', value: 'pending' },
{ label: '直接发布', value: 'publish' },
{ label: '自动草稿', value: 'draft' },
],
dependsOn: { key: 'front_submit_enabled', value: true },
},
{ key: 'front_submit_cover_required', label: '封面图必填', type: 'switch', default: false, dependsOn: { key: 'front_submit_cover', value: true } },
{ key: 'front_submit_max_images', label: '正文最大图片数', type: 'number', default: 5, min: 0, max: 50, dependsOn: { key: 'front_submit_enabled', value: true } },
],
key: 'post_article_pay_vip_1_discount',
label: '一级会员折扣',
type: 'number',
default: 100,
min: 0,
max: 100,
unit: '%',
dependsOn: { all: [{ key: 'post_article_s', value: true }, { key: 'post_article_pay_vip_price_s', value: false }] },
},
{
key: 'editor',
title: '编辑器设置',
icon: 'fa fas fa-edit',
fields: [
{
key: 'front_submit_editor_mode',
label: '编辑器模式',
type: 'radio',
default: 'rich',
options: [
{ label: '富文本', value: 'rich' },
{ label: 'Markdown', value: 'markdown' },
{ label: '纯文本', value: 'plain' },
],
dependsOn: { key: 'front_submit_content', value: true },
key: 'post_article_pay_vip_2_discount',
label: '二级会员折扣',
type: 'number',
default: 100,
min: 0,
max: 100,
unit: '%',
dependsOn: { all: [{ key: 'post_article_s', value: true }, { key: 'post_article_pay_vip_price_s', value: false }] },
description: '执行价的百分之多少,0为免费,100为没有折扣,不能高于100',
},
{ key: 'front_submit_draft_save', label: '自动保存草稿', type: 'switch', default: true, dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'front_submit_leave_warning', label: '离开页面提醒', type: 'switch', default: true, dependsOn: { key: 'front_submit_enabled', value: true } },
],
},
{
key: 'paid',
title: '付费投稿权限',
icon: 'fa fas fa-database',
fields: [
{ key: 'post_article_pay_free_s', label: '允许设置免费', type: 'switch', default: true, dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'post_article_pay_price_min', label: '最低价格', type: 'input', sanitize_type: 'money_decimal', default: '0.00', min: 0, max: 9999, help: '投稿可设置的最低付费金额', dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'post_article_pay_price_max', label: '最高价格', type: 'input', sanitize_type: 'money_decimal', default: '100.00', min: 0, max: 9999, help: '投稿可设置的最高付费金额', dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'post_article_pay_vip_price_s', label: '允许设置会员价', type: 'switch', default: true, dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'post_article_pay_vip_1_discount', label: 'VIP1 折扣(%)', type: 'number', default: 80, min: 0, max: 100, help: 'VIP1 会员折扣百分比,80 即 8 折', dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'post_article_pay_vip_2_discount', label: 'VIP2 折扣(%)', type: 'number', default: 50, min: 0, max: 100, help: 'VIP2 会员折扣百分比,50 即 5 折', dependsOn: { key: 'front_submit_enabled', value: true } },
{ key: 'post_t_placeholder', label: '投稿标题占位符', type: 'input', default: '请输入标题' },
{ key: 'post_c_placeholder', label: '投稿内容占位符', type: 'input', default: '请输入内容' },
],
},
],
-3
View File
@@ -131,9 +131,6 @@
bindLeaveWarning: function () {
var self = this;
if (cfg.leaveWarning === false) {
return;
}
window.addEventListener('beforeunload', function (e) {
if (self.isDirty && !self.isSubmitting && !window.post_is_save) {
e.preventDefault();
+18 -47
View File
@@ -297,56 +297,27 @@ class SchemaPostList {
'submit' => [
'key' => 'submit',
'title' => '前台投稿',
'version' => '1.0.0',
'version' => '2.0.0',
'option_key' => 'aksrt_settings',
'groups' => [
['key' => 'basic', 'title' => '基础配置', 'fields' => [
['key' => 'front_submit_enabled', 'label' => '开启前台投稿', 'type' => 'switch', 'default' => true],
['key' => 'front_submit_roles', 'label' => '允许投稿的角色', 'type' => 'input', 'default' => 'author,editor,administrator'],
['key' => 'post_article_btn_txte', 'label' => '投稿按钮文案', 'type' => 'input', 'default' => '发布文章'],
['key' => 'post_article_title_strlen_limit_min', 'label' => '标题最少字数', 'type' => 'number', 'default' => 5, 'min' => 1, 'max' => 100],
['key' => 'post_article_title_strlen_limit_max', 'label' => '标题最多字数', 'type' => 'number', 'default' => 30, 'min' => 5, 'max' => 200],
['key' => 'post_t_placeholder', 'label' => '标题占位符', 'type' => 'input', 'default' => '', 'description' => '留空使用默认'],
['key' => 'post_c_placeholder', 'label' => '内容占位符', 'type' => 'textarea', 'default' => '', 'description' => '留空使用默认'],
['key' => 'submit', 'title' => '前台投稿', 'fields' => [
['key' => 'post_article_s', 'label' => '启用前台投稿', 'type' => 'switcher', 'default' => true, 'description' => '此功能启用后,可以在权限管理中设置用户的发布、审核权限'],
['key' => 'post_article_btn_txte', 'label' => '按钮文字', 'type' => 'input', 'default' => '发布文章', 'dependsOn' => ['key' => 'post_article_s', 'value' => true], 'description' => '投稿按钮的显示的文字,推荐4个字更加协调'],
['key' => 'post_article_cat', 'label' => '投稿允许选择的分类', 'type' => 'taxonomy_select', 'taxonomy' => 'category', 'multiple' => true, 'default' => [], 'placeholder' => '输入关键词以搜索分类', 'dependsOn' => ['key' => 'post_article_s', 'value' => true], 'description' => '投稿允许选择的分类,为空则允许选择全部分类,所选分类下如果有子分类则会自动显示,如果选择了上级分类,则不要再选该分类下的子分类。注意:请确保所选分类包含子分类总数不要超过50个,否则可能会引起页面崩溃'],
['key' => 'post_article_custom_filter_s', 'label' => '允许选择高级筛选', 'type' => 'switcher', 'default' => true, 'dependsOn' => ['key' => 'post_article_s', 'value' => true], 'description' => '此功能启用后,请先在文章列表/高级筛选中添加高级筛选明细'],
['key' => 'post_article_tag', 'label' => '允许插入标签', 'type' => 'switcher', 'default' => true, 'dependsOn' => ['key' => 'post_article_s', 'value' => true], 'description' => '前台投稿时候允许设置文章标签'],
['key' => 'post_article_user', 'label' => '免登陆投稿发布用户', 'type' => 'user_select', 'default' => 1, 'dependsOn' => ['key' => 'post_article_s', 'value' => true], 'description' => '当选择投稿权限为无需登录就能投稿时,投稿文章的用户'],
['key' => 'post_article_title_strlen_limit', 'label' => '标题字数限制', 'type' => 'between_number', 'default' => ['min' => 5, 'max' => 30], 'unit' => '字', 'description' => '限制标题字数可有效的防止灌水等无意义内容(英文字符按0.5个字计算)'],
['key' => 'post_article_pay_free_s', 'label' => '允许设置为免费资源', 'type' => 'switcher', 'default' => true, 'dependsOn' => ['key' => 'post_article_s', 'value' => true], 'description' => '付费内容金额允许设置为 0'],
['key' => 'post_article_pay_price_limit', 'label' => '付费内容金额限制', 'type' => 'fieldset', 'default' => ['price' => ['min' => 0, 'max' => 99999], 'points' => ['min' => 0, 'max' => 0]], 'description' => '限制用户允许设置的金额,防止金额过高不合理(填0为不限制)', 'fields' => [
['key' => 'price', 'label' => '现金金额限制', 'type' => 'between_number', 'default' => ['min' => 0, 'max' => 99999]],
['key' => 'points', 'label' => '积分金额限制', 'type' => 'between_number', 'default' => ['min' => 0, 'max' => 0]],
]],
['key' => 'fields', 'title' => '表单字段', 'fields' => [
['key' => 'front_submit_title', 'label' => '标题', 'type' => 'switch', 'default' => true],
['key' => 'front_submit_content', 'label' => '正文', 'type' => 'switch', 'default' => true],
['key' => 'front_submit_excerpt', 'label' => '摘要', 'type' => 'switch', 'default' => true],
['key' => 'front_submit_cover', 'label' => '封面图', 'type' => 'switch', 'default' => true],
['key' => 'front_submit_category', 'label' => '分类选择', 'type' => 'switch', 'default' => true],
['key' => 'post_article_cat', 'label' => '允许投稿分类', 'type' => 'taxonomy_select', 'taxonomy' => 'category', 'multiple' => true, 'default' => [], 'help' => '为空则允许全部分类'],
['key' => 'front_submit_guest_enabled', 'label' => '允许免登录投稿', 'type' => 'switch', 'default' => false, 'help' => '开启后访客可投稿;文章归属到下方用户'],
['key' => 'post_article_user', 'label' => '免登录归属用户', 'type' => 'user_select', 'default' => 0, 'help' => '免登录投稿时文章归属的用户,搜索选择'],
['key' => 'front_submit_tags', 'label' => '标签输入', 'type' => 'switch', 'default' => true],
['key' => 'post_article_custom_filter_s', 'label' => '高级筛选选择', 'type' => 'switch', 'default' => true, 'help' => '投稿时可选择自定义筛选维度值'],
['key' => 'front_submit_custom_fields', 'label' => '自定义字段', 'type' => 'textarea', 'default' => ''],
]],
['key' => 'review', 'title' => '审核策略', 'fields' => [
['key' => 'front_submit_review_mode', 'label' => '审核模式', 'type' => 'radio', 'default' => 'pending', 'options' => [
['label' => '待审核', 'value' => 'pending'],
['label' => '直接发布', 'value' => 'publish'],
['label' => '自动草稿', 'value' => 'draft'],
]],
['key' => 'front_submit_cover_required', 'label' => '封面图必填', 'type' => 'switch', 'default' => false],
['key' => 'front_submit_max_images', 'label' => '正文最大图片数', 'type' => 'number', 'default' => 5, 'min' => 0, 'max' => 50],
]],
['key' => 'editor', 'title' => '编辑器设置', 'fields' => [
['key' => 'front_submit_editor_mode', 'label' => '编辑器模式', 'type' => 'radio', 'default' => 'rich', 'options' => [
['label' => '富文本', 'value' => 'rich'],
['label' => 'Markdown', 'value' => 'markdown'],
['label' => '纯文本', 'value' => 'plain'],
]],
['key' => 'front_submit_draft_save', 'label' => '自动保存草稿', 'type' => 'switch', 'default' => true],
['key' => 'front_submit_leave_warning', 'label' => '离开页面提醒', 'type' => 'switch', 'default' => true],
]],
['key' => 'paid', 'title' => '付费投稿权限', 'fields' => [
['key' => 'post_article_pay_free_s', 'label' => '允许设置免费', 'type' => 'switch', 'default' => true],
['key' => 'post_article_pay_price_min', 'label' => '最低价格', 'type' => 'input', 'sanitize_type' => 'money_decimal', 'default' => '0.00', 'min' => 0, 'max' => 9999, 'help' => '投稿可设置的最低付费金额'],
['key' => 'post_article_pay_price_max', 'label' => '最高价格', 'type' => 'input', 'sanitize_type' => 'money_decimal', 'default' => '100.00', 'min' => 0, 'max' => 9999, 'help' => '投稿可设置的最高付费金额'],
['key' => 'post_article_pay_vip_price_s', 'label' => '允许设置会员价', 'type' => 'switch', 'default' => true],
['key' => 'post_article_pay_vip_1_discount', 'label' => 'VIP1 折扣(%)', 'type' => 'number', 'default' => 80, 'min' => 0, 'max' => 100, 'help' => 'VIP1 会员折扣百分比,80 即 8 折'],
['key' => 'post_article_pay_vip_2_discount', 'label' => 'VIP2 折扣(%)', 'type' => 'number', 'default' => 50, 'min' => 0, 'max' => 100, 'help' => 'VIP2 会员折扣百分比,50 即 5 折'],
['key' => 'post_article_pay_vip_price_s', 'label' => '付费内容允许设置会员价', 'type' => 'switcher', 'default' => true, 'dependsOn' => ['key' => 'post_article_s', 'value' => true], 'description' => '前台投稿时对拥有设置付费内容权限的用户,是否开启设置会员价格。开启此项,会直接在前台显示设置会员价的选项;关闭此项,则用户只能设置普通价格,会员价则按照下方设置的折扣自动计算'],
['key' => 'post_article_pay_vip_1_discount', 'label' => '一级会员折扣', 'type' => 'number', 'default' => 100, 'min' => 0, 'max' => 100, 'unit' => '%', 'dependsOn' => ['all' => [['key' => 'post_article_s', 'value' => true], ['key' => 'post_article_pay_vip_price_s', 'value' => false]]]],
['key' => 'post_article_pay_vip_2_discount', 'label' => '二级会员折扣', 'type' => 'number', 'default' => 100, 'min' => 0, 'max' => 100, 'unit' => '%', 'dependsOn' => ['all' => [['key' => 'post_article_s', 'value' => true], ['key' => 'post_article_pay_vip_price_s', 'value' => false]]], 'description' => '执行价的百分之多少,0为免费,100为没有折扣,不能高于100'],
['key' => 'post_t_placeholder', 'label' => '投稿标题占位符', 'type' => 'input', 'default' => '请输入标题'],
['key' => 'post_c_placeholder', 'label' => '投稿内容占位符', 'type' => 'input', 'default' => '请输入内容'],
]],
],
],
+12 -12
View File
@@ -227,29 +227,33 @@ class FrontSubmit {
}
return [
'enabled' => true,
'btn_text' => '发布文章',
'title_min' => 5,
'title_max' => 30,
'title_placeholder' => '请输入标题',
'content_placeholder' => '请输入内容',
'allowed_cat_ids' => [],
'default_user_id' => 0,
'guest_enabled' => false,
'allow_category' => true,
'default_user_id' => 1,
'allow_tags' => true,
'allow_cover' => true,
'custom_filter_s' => true,
'review_mode' => 'pending',
'pay_free_s' => true,
'pay_price_min' => 0,
'pay_price_max' => 100,
'pay_price_max' => 0,
'pay_points_min' => 0,
'pay_points_max' => 0,
'pay_vip_price_s' => true,
'pay_vip_1_enabled' => false,
'pay_vip_2_enabled' => false,
'pay_vip_1_discount' => 80,
'pay_vip_2_discount' => 50,
'pay_vip_1_discount' => 100,
'pay_vip_2_discount' => 100,
];
}
/**
* Whether the user (or guest) may open / create a submission.
*
* Guest submission is granted through the capability matrix ("all" column
* of new_post_add), mirroring the reference theme.
*/
public function can_submit(?int $user_id = null): bool {
$settings = $this->settings();
@@ -261,10 +265,6 @@ class FrontSubmit {
$user_id = get_current_user_id();
}
if ($user_id <= 0) {
return !empty($settings['guest_enabled']) && (int) ($settings['default_user_id'] ?? 0) > 0;
}
return $this->user_can_cap('new_post_add', $user_id);
}
+6 -11
View File
@@ -73,8 +73,8 @@ trait FrontSubmitPay {
if ($pay_modo === 'points') {
$points = $this->parse_front_points($raw['points_price'] ?? $data['points_price'] ?? null);
$min = $this->parse_front_points_limit($settings['pay_price_min'] ?? '0.00');
$max = $this->parse_front_points_limit($settings['pay_price_max'] ?? '0.00');
$min = max(0, (int) ($settings['pay_points_min'] ?? 0));
$max = max(0, (int) ($settings['pay_points_max'] ?? 0));
if ($points === null) {
return ['success' => false, 'message' => __('请设置正确的积分价格', 'aksrt')];
}
@@ -119,8 +119,10 @@ trait FrontSubmitPay {
$meta['vip2_price'] = '0.00';
} else {
$price_minor = $this->parse_front_cash_minor($raw['price'] ?? null);
$min_minor = $this->parse_front_cash_minor($settings['pay_price_min'] ?? '0') ?? 0;
$max_minor = $this->parse_front_cash_minor($settings['pay_price_max'] ?? '0') ?? 0;
$min_yuan = max(0, (int) ($settings['pay_price_min'] ?? 0));
$max_yuan = max(0, (int) ($settings['pay_price_max'] ?? 0));
$min_minor = $min_yuan > 0 ? \AKSRT\Ledger\AssetAmount::balance((string) $min_yuan)->minor() : 0;
$max_minor = $max_yuan > 0 ? \AKSRT\Ledger\AssetAmount::balance((string) $max_yuan)->minor() : 0;
if ($price_minor === null) {
return ['success' => false, 'message' => __('请设置正确的价格', 'aksrt')];
}
@@ -199,13 +201,6 @@ trait FrontSubmitPay {
}
}
private function parse_front_points_limit($value): int {
if (!is_string($value) || !preg_match('/^(0|[1-9]\d*)(?:\.00)?$/', trim($value), $matches)) {
return 0;
}
return $this->parse_front_points((string) $matches[1]) ?? 0;
}
/**
* @param array<string, mixed> $meta
*/
+10 -18
View File
@@ -32,7 +32,7 @@ trait FrontSubmitSave {
}
if ($is_guest) {
if (empty($settings['guest_enabled']) || (int) $settings['default_user_id'] <= 0) {
if ((int) $settings['default_user_id'] <= 0) {
return ['success' => false, 'message' => __('请先登录', 'aksrt')];
}
if ($is_draft) {
@@ -93,19 +93,16 @@ trait FrontSubmitSave {
if ($this->text_length(wp_strip_all_tags($content)) < 10) {
return ['success' => false, 'message' => __('文章内容过少', 'aksrt')];
}
if (!empty($settings['allow_category']) && empty($categories)) {
if (empty($categories)) {
return ['success' => false, 'message' => __('请选择文章分类', 'aksrt')];
}
if (!empty($settings['cover_required']) && empty($data['featured_data']) && empty($data['thumbnail'])) {
return ['success' => false, 'message' => __('请设置封面图', 'aksrt')];
}
}
// Allowed category whitelist.
$allowed = $settings['allowed_cat_ids'] ?? [];
if (!empty($allowed) && !empty($categories)) {
$categories = array_values(array_intersect($categories, $allowed));
if (!$is_draft && empty($categories) && !empty($settings['allow_category'])) {
if (!$is_draft && empty($categories)) {
return ['success' => false, 'message' => __('所选分类不可用', 'aksrt')];
}
}
@@ -126,7 +123,7 @@ trait FrontSubmitSave {
$status = 'draft';
if (!$is_draft) {
$status = $this->resolve_publish_status($user_id, $settings);
$status = $this->resolve_publish_status($user_id);
}
$can_iframe = $this->user_can_cap('new_post_iframe_video', $user_id);
@@ -173,7 +170,7 @@ trait FrontSubmitSave {
}
// Re-apply categories when empty update should clear (logged-in only).
if (!empty($settings['allow_category']) && isset($data['category'])) {
if (isset($data['category'])) {
wp_set_post_categories((int) $in_id, $categories);
}
if (!empty($settings['allow_tags']) && array_key_exists('tags', $data) && $tags_raw === '') {
@@ -233,17 +230,12 @@ trait FrontSubmitSave {
}
/**
* @param array<string, mixed> $settings
* Publish status for a non-draft submission.
*
* Mirrors the reference theme: pending unless the user holds the
* "publish without review" capability.
*/
private function resolve_publish_status(int $user_id, array $settings): string {
$mode = (string) ($settings['review_mode'] ?? 'pending');
if ($mode === 'draft') {
return 'draft';
}
if ($mode === 'publish') {
return 'publish';
}
// pending mode: skip audit when capability grants it.
private function resolve_publish_status(int $user_id): string {
if ($this->user_can_cap('new_post_audit_no', $user_id)) {
return 'publish';
}
+21 -43
View File
@@ -297,65 +297,43 @@ class PostDisplay {
public static function get_submit_settings(): array {
$settings = Settings::get_all();
$money_setting = static function ($value, string $default): string {
if (!is_string($value)) {
return $default;
}
try {
return \AKSRT\Ledger\AssetAmount::balance($value)->decimal();
} catch (\InvalidArgumentException $e) {
return $default;
}
};
$title_min = max(1, min(100, (int) ($settings['post_article_title_strlen_limit_min'] ?? 5)));
$title_max = max(5, min(200, (int) ($settings['post_article_title_strlen_limit_max'] ?? 30)));
$title_limit = is_array($settings['post_article_title_strlen_limit'] ?? null)
? $settings['post_article_title_strlen_limit']
: [];
$title_min = max(1, min(100, (int) ($title_limit['min'] ?? 5)));
$title_max = max(5, min(200, (int) ($title_limit['max'] ?? 30)));
if ($title_max < $title_min) {
$title_max = $title_min;
}
$review_mode = sanitize_key((string) ($settings['front_submit_review_mode'] ?? 'pending'));
if (!in_array($review_mode, ['pending', 'publish', 'draft'], true)) {
$review_mode = 'pending';
}
$editor_mode = sanitize_key((string) ($settings['front_submit_editor_mode'] ?? 'rich'));
if (!in_array($editor_mode, ['rich', 'markdown', 'plain'], true)) {
$editor_mode = 'rich';
}
// 付费金额限制:现金/积分各自独立,0 表示不限制。
$pay_price_limit = is_array($settings['post_article_pay_price_limit'] ?? null)
? $settings['post_article_pay_price_limit']
: [];
$cash_limit = is_array($pay_price_limit['price'] ?? null) ? $pay_price_limit['price'] : [];
$points_limit = is_array($pay_price_limit['points'] ?? null) ? $pay_price_limit['points'] : [];
return [
'enabled' => !isset($settings['front_submit_enabled']) || !empty($settings['front_submit_enabled']),
'enabled' => !isset($settings['post_article_s']) || !empty($settings['post_article_s']),
'btn_text' => sanitize_text_field((string) ($settings['post_article_btn_txte'] ?? '')) ?: __('发布文章', 'aksrt'),
'title_min' => $title_min,
'title_max' => $title_max,
'title_placeholder' => sanitize_text_field((string) ($settings['post_t_placeholder'] ?? '')) ?: __('请输入标题', 'aksrt'),
'content_placeholder' => sanitize_textarea_field((string) ($settings['post_c_placeholder'] ?? '')) ?: __('请输入内容', 'aksrt'),
'allowed_cat_ids' => is_array($settings['post_article_cat'] ?? null) ? array_values(array_filter(array_map('intval', $settings['post_article_cat']))) : [],
'default_user_id' => max(0, (int) ($settings['post_article_user'] ?? 0)),
'guest_enabled' => !empty($settings['front_submit_guest_enabled']),
'allow_title' => !isset($settings['front_submit_title']) || !empty($settings['front_submit_title']),
'allow_content' => !isset($settings['front_submit_content']) || !empty($settings['front_submit_content']),
'allow_excerpt' => !isset($settings['front_submit_excerpt']) || !empty($settings['front_submit_excerpt']),
'allow_cover' => !isset($settings['front_submit_cover']) || !empty($settings['front_submit_cover']),
'allow_category' => !isset($settings['front_submit_category']) || !empty($settings['front_submit_category']),
'allow_tags' => !isset($settings['front_submit_tags']) || !empty($settings['front_submit_tags']),
'tags_s' => !isset($settings['front_submit_tags']) || !empty($settings['front_submit_tags']),
'cover_required' => !empty($settings['front_submit_cover_required']),
'max_images' => max(0, min(50, (int) ($settings['front_submit_max_images'] ?? 5))),
'review_mode' => $review_mode,
'editor_mode' => $editor_mode,
'draft_save' => !isset($settings['front_submit_draft_save']) || !empty($settings['front_submit_draft_save']),
'leave_warning' => !isset($settings['front_submit_leave_warning']) || !empty($settings['front_submit_leave_warning']),
'default_user_id' => max(0, (int) ($settings['post_article_user'] ?? 1)),
'allow_tags' => !isset($settings['post_article_tag']) || !empty($settings['post_article_tag']),
'custom_filter_s' => !isset($settings['post_article_custom_filter_s']) || !empty($settings['post_article_custom_filter_s']),
'pay_free_s' => !isset($settings['post_article_pay_free_s']) || !empty($settings['post_article_pay_free_s']),
'pay_price_min' => $money_setting($settings['post_article_pay_price_min'] ?? '0.00', '0.00'),
'pay_price_max' => $money_setting($settings['post_article_pay_price_max'] ?? '100.00', '100.00'),
'pay_price_min' => max(0, (int) ($cash_limit['min'] ?? 0)),
'pay_price_max' => max(0, (int) ($cash_limit['max'] ?? 0)),
'pay_points_min' => max(0, (int) ($points_limit['min'] ?? 0)),
'pay_points_max' => max(0, (int) ($points_limit['max'] ?? 0)),
'pay_vip_price_s' => !isset($settings['post_article_pay_vip_price_s']) || !empty($settings['post_article_pay_vip_price_s']),
'pay_vip_1_enabled' => !empty($settings['pay_user_vip_1_s']),
'pay_vip_2_enabled' => !empty($settings['pay_user_vip_2_s']),
'pay_vip_1_discount' => max(0, min(100, (int) ($settings['post_article_pay_vip_1_discount'] ?? 80))),
'pay_vip_2_discount' => max(0, min(100, (int) ($settings['post_article_pay_vip_2_discount'] ?? 50))),
'custom_filter_s' => !isset($settings['post_article_custom_filter_s']) || !empty($settings['post_article_custom_filter_s']),
'pay_vip_1_discount' => max(0, min(100, (int) ($settings['post_article_pay_vip_1_discount'] ?? 100))),
'pay_vip_2_discount' => max(0, min(100, (int) ($settings['post_article_pay_vip_2_discount'] ?? 100))),
];
}
-8
View File
@@ -26,13 +26,6 @@ if (empty($ctx['enabled'])) {
return;
}
// Guest without guest mode → login.
if (!empty($ctx['is_guest']) && empty($ctx['settings']['guest_enabled'])) {
$login = function_exists('aksrt_get_login_url') ? aksrt_get_login_url(get_permalink()) : wp_login_url(get_permalink());
wp_safe_redirect($login);
exit;
}
// Invalid edit id → strip.
if (!empty($_GET['edit']) && empty($ctx['edit_post'])) {
wp_safe_redirect(remove_query_arg('edit'));
@@ -103,7 +96,6 @@ if (file_exists($js)) {
],
'leaveWarning' => !empty($ctx['settings']['leave_warning']),
'imageUploadMultiple' => $image_upload_multiple,
'ai' => [
'available' => !empty($ctx['ai_available']),
-2
View File
@@ -175,8 +175,6 @@ if ($is_guest) {
$submit_label = __('审核', 'aksrt');
} elseif ($edit_post && in_array($post_status, ['publish', 'pending'], true)) {
$submit_label = __('保存', 'aksrt');
} elseif (($settings['review_mode'] ?? 'pending') === 'pending' && !$cap('new_post_audit_no')) {
$submit_label = __('审核', 'aksrt');
}
$ai_available = class_exists('\AKSRT\Ai\AI') && \AKSRT\Ai\AI::get_instance()->is_available();
-3
View File
@@ -7,9 +7,6 @@
*/
defined('ABSPATH') || exit;
if (empty($ctx['settings']['allow_cover'])) {
return;
}
if (empty($ctx['can_cover_image']) && empty($ctx['can_cover_slide']) && empty($ctx['can_cover_video'])) {
return;
}
@@ -2,12 +2,10 @@
/** @var array $ctx */
defined('ABSPATH') || exit;
$settings = $ctx['settings'];
$is_can_new = !empty($ctx['is_can_new']);
$status = (string) $ctx['post_status'];
$can_draft = !empty($ctx['user_id'])
&& empty($ctx['is_guest'])
&& !empty($settings['draft_save'])
&& !in_array($status, ['publish', 'pending'], true);
?>
<div class="zib-widget">
-2
View File
@@ -25,7 +25,6 @@ require_once get_template_directory() . '/templates/parts/submit/term-checks.php
<div class="zib-widget mb10-sm">
<div class="title-theme mb10"><?php esc_html_e('文章参数', 'aksrt'); ?></div>
<div class="term-select-box">
<?php if (!empty($settings['allow_category'])) : ?>
<div class="newpost-cat-drop drop-select dropdown dependency-box">
<button type="button" data-toggle-class="open" data-target=".newpost-cat-drop" class="flex ac jsb drop-btn form-control mb6">
<span class="title-theme222"><i class="fa fas fa-folder-open mr6" aria-hidden="true"></i><?php esc_html_e('分类', 'aksrt'); ?></span><i class="ml6 fa fas fa-angle-right em12"></i>
@@ -42,7 +41,6 @@ require_once get_template_directory() . '/templates/parts/submit/term-checks.php
</div>
</div>
</div>
<?php endif; ?>
<?php if (!empty($settings['custom_filter_s']) && !empty($ctx['custom_dimensions'])) : ?>
<?php foreach ($ctx['custom_dimensions'] as $dimension) :
@@ -0,0 +1,183 @@
'use strict';
/**
* 「前台投稿」后台设置页契约(对齐参考主题 1:1,不含专题):
* 1) PHP schema(SchemaPostList.php submit section)字段键、顺序、默认值与
* JS schema(assets/admin/src/schema/sections/post-list/submit.js)一致;
* 2) 参考主题字段全集存在:post_article_s / post_article_btn_txte / post_article_cat /
* post_article_custom_filter_s / post_article_tag / post_article_user /
* post_article_title_strlen_limit / post_article_pay_free_s /
* post_article_pay_price_limit / post_article_pay_vip_price_s /
* post_article_pay_vip_1_discount / post_article_pay_vip_2_discount /
* post_t_placeholder / post_c_placeholder;
* 3) 专题(topics)相关字段不存在;
* 4) 旧 AKSRT 私有字段(front_submit_*、post_article_title_strlen_limit_min/max、
* post_article_pay_price_min/max)已彻底移除,无双路兼容;
* 5) 运行时(PostDisplay::get_submit_settings)只读取新键。
*/
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const test = require('node:test');
const root = path.resolve(__dirname, '..', '..');
const php = fs.readFileSync(path.join(root, 'src/Admin/Schema/SchemaPostList.php'), 'utf8');
const js = fs.readFileSync(path.join(root, 'assets/admin/src/schema/sections/post-list/submit.js'), 'utf8');
const runtime = fs.readFileSync(path.join(root, 'src/Settings/PostDisplay.php'), 'utf8');
const REFERENCE_KEYS = [
'post_article_s',
'post_article_btn_txte',
'post_article_cat',
'post_article_custom_filter_s',
'post_article_tag',
'post_article_user',
'post_article_title_strlen_limit',
'post_article_pay_free_s',
'post_article_pay_price_limit',
'post_article_pay_vip_price_s',
'post_article_pay_vip_1_discount',
'post_article_pay_vip_2_discount',
'post_t_placeholder',
'post_c_placeholder',
];
// PHP 源码中字段定义的完整出现顺序(含 post_article_pay_price_limit 的
// fieldset 嵌套子字段 price / points)。
const PHP_FIELD_ORDER = [
...REFERENCE_KEYS.slice(0, REFERENCE_KEYS.indexOf('post_article_pay_vip_price_s')),
'price',
'points',
...REFERENCE_KEYS.slice(REFERENCE_KEYS.indexOf('post_article_pay_vip_price_s')),
];
const LEGACY_KEYS = [
'front_submit_enabled',
'front_submit_roles',
'front_submit_title',
'front_submit_content',
'front_submit_excerpt',
'front_submit_cover',
'front_submit_category',
'front_submit_guest_enabled',
'front_submit_tags',
'front_submit_custom_fields',
'front_submit_review_mode',
'front_submit_cover_required',
'front_submit_max_images',
'front_submit_editor_mode',
'front_submit_draft_save',
'front_submit_leave_warning',
'post_article_title_strlen_limit_min',
'post_article_title_strlen_limit_max',
'post_article_pay_price_min',
'post_article_pay_price_max',
];
/** Extract the PHP 'submit' => [ ... ] section body (balanced brackets). */
function phpSubmitSection(src) {
const start = src.indexOf("'submit' => [");
assert.notEqual(start, -1, 'PHP schema has a submit section');
const open = src.indexOf('[', start);
let depth = 0;
for (let i = open; i < src.length; i++) {
const ch = src[i];
if (ch === "'" || ch === '"') {
const quote = ch;
i++;
while (i < src.length) {
if (src[i] === '\\') { i += 2; continue; }
if (src[i] === quote) break;
i++;
}
continue;
}
if (ch === '[') depth++;
else if (ch === ']') {
depth--;
if (depth === 0) return src.slice(open, i + 1);
}
}
throw new Error('unbalanced submit section');
}
const submitPhp = phpSubmitSection(php);
test('PHP submit section 字段键与参考主题一致且顺序相同', () => {
// 字段定义均为 ['key' => '...', 'label' => ...] 开头;dependsOn 内的
// ['key' => '...', 'value' => ...] 不是字段定义,须排除。
const found = [];
const re = /'key'\s*=>\s*'([a-z0-9_]+)',\s*'label'/g;
let m;
while ((m = re.exec(submitPhp)) !== null) found.push(m[1]);
assert.deepEqual(found, PHP_FIELD_ORDER);
});
test('PHP submit section 不含专题字段', () => {
assert.doesNotMatch(submitPhp, /post_article_topics/);
assert.doesNotMatch(submitPhp, /'topics'/);
});
test('PHP submit section 默认值对齐参考主题', () => {
assert.match(submitPhp, /'post_article_s',\s*'label'\s*=>\s*'启用前台投稿',\s*'type'\s*=>\s*'switcher',\s*'default'\s*=>\s*true/);
assert.match(submitPhp, /'post_article_btn_txte',\s*'label'\s*=>\s*'按钮文字',\s*'type'\s*=>\s*'input',\s*'default'\s*=>\s*'发布文章'/);
assert.match(submitPhp, /'post_article_user',\s*'label'\s*=>\s*'免登陆投稿发布用户',\s*'type'\s*=>\s*'user_select',\s*'default'\s*=>\s*1/);
assert.match(submitPhp, /'post_article_title_strlen_limit',\s*'label'\s*=>\s*'标题字数限制',\s*'type'\s*=>\s*'between_number',\s*'default'\s*=>\s*\['min'\s*=>\s*5,\s*'max'\s*=>\s*30\]/);
assert.match(submitPhp, /'post_article_pay_vip_1_discount',\s*'label'\s*=>\s*'一级会员折扣',\s*'type'\s*=>\s*'number',\s*'default'\s*=>\s*100/);
assert.match(submitPhp, /'post_article_pay_vip_2_discount',\s*'label'\s*=>\s*'二级会员折扣',\s*'type'\s*=>\s*'number',\s*'default'\s*=>\s*100/);
assert.match(submitPhp, /'post_t_placeholder',\s*'label'\s*=>\s*'投稿标题占位符',\s*'type'\s*=>\s*'input',\s*'default'\s*=>\s*'请输入标题'/);
assert.match(submitPhp, /'post_c_placeholder',\s*'label'\s*=>\s*'投稿内容占位符',\s*'type'\s*=>\s*'input',\s*'default'\s*=>\s*'请输入内容'/);
assert.match(submitPhp, /'price',\s*'label'\s*=>\s*'现金金额限制'/);
assert.match(submitPhp, /'points',\s*'label'\s*=>\s*'积分金额限制'/);
});
test('会员折扣仅在关闭手动会员价时显示(对齐参考主题 dependency)', () => {
assert.match(
submitPhp,
/'post_article_pay_vip_1_discount'[\s\S]*?'dependsOn'\s*=>\s*\['all'\s*=>\s*\[\['key'\s*=>\s*'post_article_s',\s*'value'\s*=>\s*true\],\s*\['key'\s*=>\s*'post_article_pay_vip_price_s',\s*'value'\s*=>\s*false\]\]\]/
);
assert.match(
submitPhp,
/'post_article_pay_vip_2_discount'[\s\S]*?'dependsOn'\s*=>\s*\['all'\s*=>\s*\[\['key'\s*=>\s*'post_article_s',\s*'value'\s*=>\s*true\],\s*\['key'\s*=>\s*'post_article_pay_vip_price_s',\s*'value'\s*=>\s*false\]\]\]/
);
});
test('JS schema 与 PHP 字段键一致(ui_only content 行除外)', () => {
// 字段定义为 { key: '...', label: ... };dependsOn 内的 { key, value } 须排除。
const keys = [];
const re = /key:\s*'([a-z0-9_]+)',\s*label:/g;
let m;
while ((m = re.exec(js)) !== null) keys.push(m[1]);
const persisted = keys.filter((k) => REFERENCE_KEYS.includes(k));
assert.deepEqual(persisted, REFERENCE_KEYS);
for (const legacy of LEGACY_KEYS) {
assert.ok(!keys.includes(legacy), `JS schema 残留旧字段: ${legacy}`);
}
// 两个 ui_only 提示行承载参考主题 desc 中的【去设置】链接。
assert.match(js, /permissions\/capabilities/);
assert.match(js, /post-list\/filter/);
assert.match(js, /ui_only:\s*true/);
});
test('JS schema 默认值对齐参考主题', () => {
assert.match(js, /post_article_user:\s*1\b/);
assert.match(js, /post_article_pay_vip_1_discount:\s*100\b/);
assert.match(js, /post_article_pay_vip_2_discount:\s*100\b/);
assert.match(js, /post_t_placeholder:\s*'请输入标题'/);
assert.match(js, /post_c_placeholder:\s*'请输入内容'/);
assert.match(js, /price:\s*\{\s*min:\s*0,\s*max:\s*99999\s*\}/);
});
test('旧字段在 schema 与运行时中均已移除(无双路)', () => {
for (const legacy of LEGACY_KEYS) {
assert.ok(!php.includes(legacy), `PHP schema 残留旧字段: ${legacy}`);
assert.ok(!runtime.includes(legacy), `PostDisplay 残留旧字段: ${legacy}`);
}
// 运行时读取新键。
assert.match(runtime, /\$settings\['post_article_s'\]/);
assert.match(runtime, /\$settings\['post_article_title_strlen_limit'\]/);
assert.match(runtime, /\$settings\['post_article_pay_price_limit'\]/);
assert.match(runtime, /\$settings\['post_article_tag'\]/);
assert.match(runtime, /\$settings\['post_article_user'\]/);
});
+37 -36
View File
@@ -1,5 +1,5 @@
{
"generated_at": "2026-09-06T05:00:37+00:00",
"generated_at": "2026-09-24T04:13:34+00:00",
"errors": [],
"warnings": [
"customPage tools-update section 'tools/update' not in PHP schema (ok if pure operational page)",
@@ -15,13 +15,12 @@
"enum incomplete parse for 'content_audit_provider' (php subset of js): php=[baidu] js=[baidu,null]",
"enum incomplete parse for 'epay_device' (php subset of js): php=[auto] js=[auto,pc,mobile]",
"enum incomplete parse for 'font_family' (php subset of js): php=[system] js=[system,noto-sans-sc,noto-serif-sc,custom]",
"enum incomplete parse for 'front_submit_editor_mode' (php subset of js): php=[rich] js=[rich,markdown,plain]",
"enum incomplete parse for 'front_submit_review_mode' (php subset of js): php=[pending] js=[pending,publish,draft]",
"enum incomplete parse for 'i18n_default_lang' (php subset of js): php=[zh-CN] js=[zh-CN,en,zh-TW,ja,ko,fr,de,es,ru]",
"enum incomplete parse for 'i18n_switcher_position' (php subset of js): php=[header] js=[header,footer,both,none]",
"enum incomplete parse for 'i18n_url_strategy' (php subset of js): php=[query] js=[query,path,subdomain]",
"enum incomplete parse for 'img_position' (php subset of js): php=[left] js=[left,right]",
"enum incomplete parse for 'invit_code_s' (php subset of js): php=[close] js=[close,open,must]",
"enum incomplete parse for 'invite_code_s' (php subset of js): php=[close] js=[close,open,must]",
"enum incomplete parse for 'ip_addr_sdk' (php subset of js): php=[polling] js=[polling,qq,amap,null]",
"enum incomplete parse for 'ip_geo_format' (php subset of js): php=[province_city] js=[province_city,province,country_province]",
"enum incomplete parse for 'lazy_animation' (php subset of js): php=[fade] js=[blur,fade,scale]",
@@ -35,13 +34,18 @@
"enum incomplete parse for 'oauth_bind_type' (php subset of js): php=[auto] js=[auto,manual]",
"enum incomplete parse for 'oauth_proxy_mode' (php subset of js): php=[close] js=[close,server,client]",
"enum incomplete parse for 'paging_ajax_s' (php subset of js): php=[1] js=[1,0]",
"enum incomplete parse for 'pattern' (php subset of js): php=[allow] js=[allow,prohibit]",
"enum incomplete parse for 'pay_alipay_sdk_options' (php subset of js): php=[official_alipay] js=[official_alipay,epay,null]",
"enum incomplete parse for 'pay_box_position' (php subset of js): php=[box_top] js=[box_top,top,bottom,box_bottom]",
"enum incomplete parse for 'pay_modo_default' (php subset of js): php=[0] js=[0,points]",
"enum incomplete parse for 'pay_wechat_sdk_options' (php subset of js): php=[official_wechat] js=[official_wechat,epay,null]",
"enum incomplete parse for 'post_author_card_orderby' (php subset of js): php=[views] js=[views,date,modified,comment_count]",
"enum incomplete parse for 'post_author_card_style' (php subset of js): php=[card] js=[card,list]",
"enum incomplete parse for 'post_pay_box_position' (php subset of js): php=[content] js=[content,mask]",
"enum incomplete parse for 'post_related_orderby' (php subset of js): php=[modified] js=[modified,date,views,like,comment_count,favorite,rand]",
"enum incomplete parse for 'post_related_type' (php subset of js): php=[img] js=[img,list,text]",
"enum incomplete parse for 'post_time_source' (php subset of js): php=[date] js=[date,modified]",
"enum incomplete parse for 'referral_attribution_model' (php subset of js): php=[first_touch] js=[first_touch,last_touch]",
"enum incomplete parse for 'search_type_in' (php subset of js): php=[post] js=[post,user]",
"enum incomplete parse for 'sign_card_position' (php subset of js): php=[left] js=[left,center,right]",
"enum incomplete parse for 'sign_theme_mode' (php subset of js): php=[no] js=[no,white-theme,dark-theme]",
@@ -62,7 +66,7 @@
"info": [
"PHP schema domains: global, page_display, post_list, permissions, users, payment, extensions, tools, ExtensionsAudit, ExtensionsIP, ExtensionsPush, ToolsBackup, ToolsHealth, ToolsImportExport",
"Menu pages discovered: 61",
"admin build ok; chunks=32"
"admin build ok; chunks=30"
],
"domains": {
"global": {
@@ -147,9 +151,8 @@
"payment": {
"sections": [
"affiliate",
"card-pass",
"gateway",
"order",
"knowledge",
"recharge",
"revenue",
"vip",
@@ -234,38 +237,36 @@
"entry": true,
"missing_chunks": [],
"chunks": [
"SchemaPage.CcW0AW7T.js",
"vendor-vue.BxZIRU0_.js",
"shared-api.BUPhZW2Y.js",
"FaIcon.NZ6TDkNu.js",
"shared-api.DnsQ5cxS.js",
"vendor-misc.bELTaXdf.js",
"SchemaPage.C2bnpARq.js",
"vendor-vue.BYzo-2I-.js",
"FaIcon.B3OOcphx.js",
"FaIconPicker.DHrC0Y72.js",
"shared-api.BvxssbgC.js",
"vendor-misc.buu8cFA9.js",
"level.E3ANSDAX.js",
"badge.CKTsmH1z.js",
"vendor-naive.CKYCZmXD.js",
"DeferredPage.DpQpYrho.js",
"NativeOpsRedirect.CHwEgYbu.js",
"FloatingButtonsSettings.JM4lmjpr.js",
"vendor-draggable.BooRVfGb.js",
"PageHeader.CtT29f8Y.js",
"FooterTabbarSettings.C6AggjrQ.js",
"PostPageSettings.uzxR41nA.js",
"CommentSettings.sqwcq8XD.js",
"PermissionsCapabilities.CjA3yZya.js",
"AttachmentPermissions.Dzsg-DfQ.js",
"CmsCredits.BYsXdX89.js",
"ThemeInfoPage.jxAxkM2b.js",
"ThemeAuthorizationPage.DMbNRHuq.js",
"DocsPage.mFfiXsYT.js",
"UsersVerify.ryf_AQd6.js",
"UsersLevel.BpnbcbVe.js",
"UsersBadge.DCbaumfe.js",
"UsersWechatTemplate.Dn21sVHP.js",
"PaymentGateway.DuX_0Di_.js",
"ToolsImportExport.BxEsl-fY.js",
"ToolsHealth.B1bVNkRU.js",
"ToolsUpdate.DZedmIdt.js",
"ExtensionAI.BmvoDo9B.js"
"vendor-naive.D3KCxD1U.js",
"DeferredPage.BR2FUrUF.js",
"NativeOpsRedirect.DMOc4MZt.js",
"FloatingButtonsSettings.ChAj9F5j.js",
"vendor-draggable.YNevSrwY.js",
"PageHeader.jmNZVzHG.js",
"FooterTabbarSettings.CwSsjNlJ.js",
"PostPageSettings.DZzG8fRg.js",
"CommentSettings.sUF8U6J1.js",
"PermissionsCapabilities.BeLUij9c.js",
"CmsCredits.CTDJTkG-.js",
"ThemeInfoPage.CbJKzVFa.js",
"ThemeAuthorizationPage.DqXs-wcM.js",
"DocsPage.0VHAQOLD.js",
"UsersVerify.BwpKCOcv.js",
"UsersLevel.BOBrM4ao.js",
"UsersBadge.BoxXBYpU.js",
"UsersWechatTemplate.CEr5O4Ax.js",
"ToolsImportExport.CAIX07JQ.js",
"ToolsHealth.DAW9Zcoi.js",
"ToolsUpdate.DlvVMvXs.js",
"ExtensionAI.CJ_ZQ8Tr.js"
]
}
}