feat(attachment): 按参考主题重构后台上传配置套件

- 新增 AKSRT\Attachment\UploadLimits:按用户类型解析图片/视频/文件
  上传上限(取最大值+默认兜底,钳制到 PHP 上限)、允许/禁止格式过滤、
  上传自动重命名、非管理员附件页 404;不含论坛角色
- 后台「附件配置」重做:大小限制/格式限制/上传行为三组配置,
  PHP Schema 与 SPA Schema 逐字段镜像(v1.2.0)
- 定制页 AttachmentPermissions.vue 改为标准 schemaPage,清理失效的
  API 包装、组件加载器与旧配置键(submit_image_max_size 等)
- 投稿/评论上传、批量上传数量全部切换到新链路;AksField 数字组件
  支持单位展示
- 更新 captcha harness 与 front-submit 契约测试;421 项测试通过
This commit is contained in:
2026-09-24 11:04:49 +08:00
parent 505d9156fe
commit d4bb43a275
16 changed files with 643 additions and 269 deletions
@@ -86,6 +86,7 @@ namespace AKSRT\Settings {
namespace {
require dirname(__DIR__, 2) . '/inc/modules/captcha.php';
require dirname(__DIR__, 2) . '/src/Attachment/UploadLimits.php';
require dirname(__DIR__, 2) . '/src/Admin/Schema/SchemaPermissions.php';
require dirname(__DIR__, 2) . '/src/Admin/SchemaProvider.php';
@@ -19,19 +19,35 @@ test('front submit enqueues the WordPress editor before wp_head is rendered', ()
test('front submit uploads use the effective WordPress server limit', () => {
const controller = read('src/Core/FrontSubmit.php');
const page = read('templates/pages/page-submit.php');
const limits = read('src/Attachment/UploadLimits.php');
assert.match(controller, /function upload_limit_bytes\(string \$kind\): int/);
assert.match(controller, /min\(\$configured_mb \* MB_IN_BYTES, \(int\) wp_max_upload_size\(\)\)/);
assert.match(controller, /UploadLimits::limit_bytes\(\$config_kind\)/);
assert.match(controller, /\$config_kind = \$kind === 'resource' \? 'file' : \$kind;/);
assert.match(controller, /UPLOAD_ERR_INI_SIZE/);
assert.match(controller, /UPLOAD_ERR_FORM_SIZE/);
assert.match(controller, /UPLOAD_ERR_PARTIAL/);
assert.match(controller, /\['status' => 413\]/);
// The effective clamp (configured limit vs PHP upload cap) lives in the limiter.
assert.match(limits, /min\(\$mb \* MB_IN_BYTES, \(int\) wp_max_upload_size\(\)\)/);
assert.match(page, /FrontSubmit::upload_limit_bytes\('image'\)/);
assert.match(page, /FrontSubmit::upload_limit_bytes\('video'\)/);
assert.match(page, /FrontSubmit::upload_limit_bytes\('resource'\)/);
assert.doesNotMatch(page, /\$attachment_settings\s*=/);
});
test('front submit image batch selection follows the admin upload config', () => {
const page = read('templates/pages/page-submit.php');
const editor = read('assets/js/front-submit-editor.js');
assert.match(page, /UploadLimits::image_batch_limit\(\)/);
assert.match(page, /'imageUploadMultiple' => \$image_upload_multiple,/);
assert.match(editor, /function imageBatchLimit\(\)/);
assert.match(editor, /Number\(cfg\.imageUploadMultiple\)/);
assert.match(editor, /multiple: batch\.multiple, maxItems: batch\.maxItems/);
assert.match(editor, /type: 'image', multiple: imageBatch\.multiple, maxItems: imageBatch\.maxItems,/);
});
test('published post content reaches the front submit editor unchanged', () => {
const context = read('templates/parts/submit/context.php');
const editor = read('templates/parts/submit/editor-main.php');