fix(admin): replicate reference advanced-filter settings page 1:1

- Rewrite post_list/filter schema (PHP + JS) with the reference theme's
  field set, order, defaults and dependencies; topics fields excluded
  (no topics taxonomy), AKSRT private filter_* toggles dropped
- Support dynamic checkbox options in AksField (options as formData key)
  so cat_custom_filter.custom_filters lists the custom_filter dimensions
- Map PostDisplay filter settings to the new keys without legacy fallback;
  cat_custom_filter now carries lists/dropdown fieldsets and array filters
- Wire the archive chain to reference semantics: cat_custom_filter
  overrides per-category filter projects, custom_filter_show gates the
  default display, dimension chip groups render on category/tag archives
- Filter archive queries (main query + AJAX endpoint) by _aksrt_cf_{key}
  meta with exact-quoted LIKE matching
- Add advanced-filter settings reference contract test
This commit is contained in:
kate522 committed 2026-09-24 15:39:25 +08:00
1 parent 4d6b2c6045
commit a8060fa71d
16 files changed
+635 -154

No files matched your search

+39
View File
@@ -108,6 +108,7 @@ class GlobalController extends ControllerBase {
'term_id' => ['type' => 'integer', 'default' => 0, 'sanitize_callback' => 'absint'],
'filter_cat' => ['type' => 'string', 'default' => '', 'sanitize_callback' => 'sanitize_text_field'],
'filter_tag' => ['type' => 'string', 'default' => '', 'sanitize_callback' => 'sanitize_text_field'],
'custom_filter' => ['type' => 'string', 'default' => '', 'sanitize_callback' => 'sanitize_text_field'],
'sort' => ['type' => 'string', 'default' => 'date', 'sanitize_callback' => 'sanitize_key'],
'page' => ['type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint'],
],
@@ -209,6 +210,44 @@ class GlobalController extends ControllerBase {
if ($tax_query !== []) {
$args['tax_query'] = $tax_query;
}
// 自定义高级筛选维度(custom_filter=JSON {dim_key:value};参考主题 meta_query LIKE 语义)。
$custom_raw = (string) $request->get_param('custom_filter');
$custom = $custom_raw !== '' ? json_decode($custom_raw, true) : [];
if (is_array($custom) && $custom !== []) {
$filter_cfg = \AKSRT\Settings\Settings::get_post_filter_settings();
$allowed = [];
foreach ($filter_cfg['custom_filter'] as $dimension) {
$dim_key = sanitize_key((string) ($dimension['key'] ?? ''));
if ($dim_key === '') {
continue;
}
$vals = [];
foreach ((array) ($dimension['vals'] ?? []) as $val) {
$vkey = sanitize_key((string) ($val['key'] ?? ''));
if ($vkey !== '') {
$vals[] = $vkey;
}
}
$allowed[$dim_key] = $vals;
}
$meta_query = [];
foreach ($custom as $dim_key => $dim_value) {
$dim_key = sanitize_key((string) $dim_key);
$dim_value = sanitize_key((string) $dim_value);
if ($dim_key === '' || $dim_value === '' || !isset($allowed[$dim_key]) || !in_array($dim_value, $allowed[$dim_key], true)) {
continue;
}
$meta_query[] = [
'key' => '_aksrt_cf_' . $dim_key,
'value' => '"' . $dim_value . '"',
'compare' => 'LIKE',
];
}
if ($meta_query !== []) {
$args['meta_query'] = $meta_query;
}
}
if (function_exists('aksrt_homepage_apply_named_sort_args')) {
$args = aksrt_homepage_apply_named_sort_args($args, $sort);
}