Add native side meta box for forum topics (plate/sticky/lock/review/pay visibility) and taxonomy form fields for aksrt_product_cat inheritance settings. Source-only changes; no SPA build artifacts.
681 lines
28 KiB
PHP
681 lines
28 KiB
PHP
<?php
|
||
/**
|
||
* AKSRT Shop Term Meta
|
||
*
|
||
* 为商品分类(aksrt_product_cat)、商品标签(aksrt_product_tag)和
|
||
* 优惠活动(shop_discount)注册 term meta 并提供 getter/setter。
|
||
*
|
||
* @package AKSRT
|
||
*/
|
||
|
||
defined('ABSPATH') || exit;
|
||
|
||
class AKSRT_Shop_Term_Meta {
|
||
|
||
private static $instance = null;
|
||
|
||
/** @var string Meta key for product_cat/product_tag unified storage */
|
||
const META_KEY = 'aksrt_shop_term_meta';
|
||
|
||
/** @var string Meta key for shop_discount unified storage */
|
||
const DISCOUNT_META_KEY = 'aksrt_shop_discount_meta';
|
||
|
||
public static function get_instance(): self {
|
||
if (null === self::$instance) {
|
||
self::$instance = new self();
|
||
}
|
||
return self::$instance;
|
||
}
|
||
|
||
/**
|
||
* Register hooks.
|
||
*/
|
||
public function init(): void {
|
||
add_action('init', [$this, 'register_discount_taxonomy'], 5);
|
||
add_action('init', [$this, 'register_term_meta_fields'], 10);
|
||
|
||
// Native term UI for shop_discount (zibll-style admin ops).
|
||
add_action('shop_discount_add_form_fields', [$this, 'render_discount_add_fields']);
|
||
add_action('shop_discount_edit_form_fields', [$this, 'render_discount_edit_fields'], 10, 1);
|
||
add_action('created_shop_discount', [$this, 'save_discount_term_fields']);
|
||
add_action('edited_shop_discount', [$this, 'save_discount_term_fields']);
|
||
|
||
// Product category inheritance fields.
|
||
add_action('aksrt_product_cat_add_form_fields', [$this, 'render_cat_add_fields']);
|
||
add_action('aksrt_product_cat_edit_form_fields', [$this, 'render_cat_edit_fields'], 10, 1);
|
||
add_action('created_aksrt_product_cat', [$this, 'save_cat_term_fields']);
|
||
add_action('edited_aksrt_product_cat', [$this, 'save_cat_term_fields']);
|
||
}
|
||
|
||
// ─── Taxonomy Registration ───────────────────────────────────
|
||
|
||
/**
|
||
* Register the shop_discount taxonomy for discount campaigns.
|
||
*/
|
||
public function register_discount_taxonomy(): void {
|
||
if (taxonomy_exists('shop_discount')) {
|
||
return;
|
||
}
|
||
|
||
$shop_enabled = true;
|
||
if (class_exists('AKSRT_Settings')) {
|
||
$shop_settings = AKSRT_Settings::get_shop_settings();
|
||
$shop_enabled = !empty($shop_settings['enabled']);
|
||
}
|
||
$shop_show_ui = true;
|
||
$shop_show_menu = is_admin() ? $shop_enabled : false;
|
||
|
||
register_taxonomy('shop_discount', 'aksrt_product', [
|
||
'labels' => [
|
||
'name' => __('优惠活动', 'aksrt'),
|
||
'singular_name' => __('优惠活动', 'aksrt'),
|
||
'search_items' => __('搜索优惠活动', 'aksrt'),
|
||
'all_items' => __('所有优惠活动', 'aksrt'),
|
||
'edit_item' => __('编辑优惠活动', 'aksrt'),
|
||
'add_new_item' => __('新增优惠活动', 'aksrt'),
|
||
'menu_name' => __('优惠活动', 'aksrt'),
|
||
],
|
||
'public' => true,
|
||
'hierarchical' => false,
|
||
'show_ui' => $shop_show_ui,
|
||
'show_in_menu' => $shop_show_menu,
|
||
'show_in_rest' => true,
|
||
'show_admin_column' => true,
|
||
'rewrite' => ['slug' => 'shop-discount', 'with_front' => false],
|
||
]);
|
||
}
|
||
|
||
// ─── Term Meta Registration ──────────────────────────────────
|
||
|
||
/**
|
||
* Register all term meta fields for REST API exposure.
|
||
*/
|
||
public function register_term_meta_fields(): void {
|
||
$auth = function () {
|
||
return current_user_can('manage_categories');
|
||
};
|
||
|
||
// ── aksrt_product_cat ──
|
||
$cat_fields = $this->get_cat_field_definitions();
|
||
foreach ($cat_fields as $key => $def) {
|
||
register_term_meta('aksrt_product_cat', $key, [
|
||
'type' => $def['type'],
|
||
'description' => $def['description'] ?? $key,
|
||
'single' => true,
|
||
'default' => $def['default'] ?? '',
|
||
'show_in_rest' => true,
|
||
'sanitize_callback' => $def['sanitize'] ?? 'sanitize_text_field',
|
||
'auth_callback' => $auth,
|
||
]);
|
||
}
|
||
|
||
// ── aksrt_product_tag ──
|
||
$tag_fields = $this->get_tag_field_definitions();
|
||
foreach ($tag_fields as $key => $def) {
|
||
register_term_meta('aksrt_product_tag', $key, [
|
||
'type' => $def['type'],
|
||
'description' => $def['description'] ?? $key,
|
||
'single' => true,
|
||
'default' => $def['default'] ?? '',
|
||
'show_in_rest' => true,
|
||
'sanitize_callback' => $def['sanitize'] ?? 'sanitize_text_field',
|
||
'auth_callback' => $auth,
|
||
]);
|
||
}
|
||
|
||
// ── shop_discount ──
|
||
$discount_fields = $this->get_discount_field_definitions();
|
||
foreach ($discount_fields as $key => $def) {
|
||
register_term_meta('shop_discount', $key, [
|
||
'type' => $def['type'],
|
||
'description' => $def['description'] ?? $key,
|
||
'single' => true,
|
||
'default' => $def['default'] ?? '',
|
||
'show_in_rest' => true,
|
||
'sanitize_callback' => $def['sanitize'] ?? 'sanitize_text_field',
|
||
'auth_callback' => $auth,
|
||
]);
|
||
}
|
||
}
|
||
|
||
// ─── Field Definitions ───────────────────────────────────────
|
||
|
||
/**
|
||
* Product category term meta field definitions.
|
||
*
|
||
* @return array<string, array{type:string, description:string, default:mixed, sanitize?:callable}>
|
||
*/
|
||
private function get_cat_field_definitions(): array {
|
||
return [
|
||
'shop_cat_limit_buy' => [
|
||
'type' => 'integer', 'description' => '分类级限购 (-1 不限)', 'default' => -1,
|
||
'sanitize' => function ($v) { return max(-1, min(9999, (int) $v)); },
|
||
],
|
||
'shop_cat_shipping_fee' => [
|
||
'type' => 'string', 'description' => '分类级运费类型', 'default' => '',
|
||
'sanitize' => function ($v) {
|
||
$v = sanitize_key((string) $v);
|
||
return in_array($v, ['', 'free', 'fixed', 'amount'], true) ? $v : '';
|
||
},
|
||
],
|
||
'shop_cat_guest_buy' => [
|
||
'type' => 'string', 'description' => '分类级免登录购买', 'default' => '',
|
||
],
|
||
'shop_cat_email_fill' => [
|
||
'type' => 'string', 'description' => '分类级邮箱必留', 'default' => '',
|
||
],
|
||
'shop_cat_after_sale' => [
|
||
'type' => 'string', 'description' => '分类级售后政策', 'default' => '',
|
||
'sanitize' => function ($v) {
|
||
$v = sanitize_key((string) $v);
|
||
return in_array($v, ['', 'refund', 'refund_return', 'none'], true) ? $v : '';
|
||
},
|
||
],
|
||
'shop_cat_rebate' => [
|
||
'type' => 'string', 'description' => '分类级返佣覆盖', 'default' => '',
|
||
],
|
||
'shop_cat_service' => [
|
||
'type' => 'string', 'description' => '分类级服务保障', 'default' => '',
|
||
'sanitize' => 'sanitize_textarea_field',
|
||
],
|
||
'shop_cat_single_tab' => [
|
||
'type' => 'string', 'description' => '分类级自定义 TAB', 'default' => '',
|
||
'sanitize' => 'sanitize_textarea_field',
|
||
],
|
||
'shop_cat_content_after' => [
|
||
'type' => 'string', 'description' => '分类级详情页底部内容', 'default' => '',
|
||
'sanitize' => 'wp_kses_post',
|
||
],
|
||
'shop_cat_content_layout' => [
|
||
'type' => 'string', 'description' => '分类级内容布局', 'default' => '',
|
||
'sanitize' => function ($v) {
|
||
$v = sanitize_key((string) $v);
|
||
return in_array($v, ['', 'adapt', 'full', 'sidebar'], true) ? $v : '';
|
||
},
|
||
],
|
||
'shop_cat_content_show_bg' => [
|
||
'type' => 'string', 'description' => '分类级详情背景盒子', 'default' => '',
|
||
],
|
||
'shop_cat_list_style' => [
|
||
'type' => 'string', 'description' => '分类页列表样式', 'default' => '',
|
||
'sanitize' => function ($v) {
|
||
$v = sanitize_key((string) $v);
|
||
return in_array($v, ['', 'default', 'card-lg', 'card-sm'], true) ? $v : '';
|
||
},
|
||
],
|
||
];
|
||
}
|
||
|
||
/**
|
||
* Product tag term meta field definitions.
|
||
*
|
||
* @return array<string, array{type:string, description:string, default:mixed, sanitize?:callable}>
|
||
*/
|
||
private function get_tag_field_definitions(): array {
|
||
return [
|
||
'shop_tag_priority' => [
|
||
'type' => 'integer', 'description' => '标签优先级(影响显示顺序)', 'default' => 0,
|
||
'sanitize' => function ($v) { return max(0, min(9999, (int) $v)); },
|
||
],
|
||
'shop_tag_class' => [
|
||
'type' => 'string', 'description' => '标签颜色 class', 'default' => '',
|
||
'sanitize' => 'sanitize_html_class',
|
||
],
|
||
'shop_tag_is_important' => [
|
||
'type' => 'string', 'description' => '重点标签(商品价格位着重显示)', 'default' => '',
|
||
],
|
||
];
|
||
}
|
||
|
||
/**
|
||
* Shop discount term meta field definitions.
|
||
*
|
||
* @return array<string, array{type:string, description:string, default:mixed, sanitize?:callable}>
|
||
*/
|
||
private function get_discount_field_definitions(): array {
|
||
return [
|
||
'shop_discount_small_badge' => [
|
||
'type' => 'string', 'description' => '小标签文案', 'default' => '',
|
||
],
|
||
'shop_discount_priority' => [
|
||
'type' => 'integer', 'description' => '优先级(数字越大越优先)', 'default' => 0,
|
||
'sanitize' => function ($v) { return max(0, min(9999, (int) $v)); },
|
||
],
|
||
'shop_discount_is_important' => [
|
||
'type' => 'string', 'description' => '重点活动', 'default' => '',
|
||
],
|
||
'shop_discount_important_class' => [
|
||
'type' => 'string', 'description' => '重点活动背景色 class', 'default' => '',
|
||
'sanitize' => 'sanitize_html_class',
|
||
],
|
||
'shop_discount_scope' => [
|
||
'type' => 'string', 'description' => '优惠范围', 'default' => 'item',
|
||
'sanitize' => function ($v) {
|
||
$v = sanitize_key((string) $v);
|
||
return in_array($v, ['item', 'product', 'author', 'order'], true) ? $v : 'item';
|
||
},
|
||
],
|
||
'shop_discount_type' => [
|
||
'type' => 'string', 'description' => '优惠类型', 'default' => 'reduction',
|
||
'sanitize' => function ($v) {
|
||
$v = sanitize_key((string) $v);
|
||
return in_array($v, ['reduction', 'discount', 'gift'], true) ? $v : 'reduction';
|
||
},
|
||
],
|
||
'shop_discount_value' => [
|
||
'type' => 'string', 'description' => '优惠数值(立减金额/折扣 0.01-9.99)', 'default' => '0',
|
||
'sanitize' => function ($v) { return sanitize_text_field((string) $v); },
|
||
],
|
||
'shop_discount_gift_config' => [
|
||
'type' => 'string', 'description' => '赠品配置 JSON', 'default' => '',
|
||
'sanitize' => 'sanitize_textarea_field',
|
||
],
|
||
'shop_discount_price_limit' => [
|
||
'type' => 'string', 'description' => '金额门槛', 'default' => '0',
|
||
'sanitize' => function ($v) { return max(0, (float) $v); },
|
||
],
|
||
'shop_discount_user_limit' => [
|
||
'type' => 'string', 'description' => '用户身份限制', 'default' => '',
|
||
'sanitize' => function ($v) {
|
||
$v = sanitize_key((string) $v);
|
||
return in_array($v, ['', 'vip', 'vip_2', 'auth'], true) ? $v : '';
|
||
},
|
||
],
|
||
'shop_discount_start' => [
|
||
'type' => 'string', 'description' => '活动开始时间', 'default' => '',
|
||
'sanitize' => 'sanitize_text_field',
|
||
],
|
||
'shop_discount_end' => [
|
||
'type' => 'string', 'description' => '活动结束时间', 'default' => '',
|
||
'sanitize' => 'sanitize_text_field',
|
||
],
|
||
'shop_discount_countdown' => [
|
||
'type' => 'string', 'description' => '倒计时显示', 'default' => '',
|
||
],
|
||
];
|
||
}
|
||
|
||
// ─── Getters ─────────────────────────────────────────────────
|
||
|
||
/**
|
||
* Get all shop term meta for a product category.
|
||
*
|
||
* @param int $term_id
|
||
* @return array
|
||
*/
|
||
public static function get_cat_meta(int $term_id): array {
|
||
$defaults = [
|
||
'limit_buy' => -1,
|
||
'shipping_fee' => '',
|
||
'guest_buy' => '',
|
||
'email_fill' => '',
|
||
'after_sale' => '',
|
||
'rebate' => '',
|
||
'service' => '',
|
||
'single_tab' => '',
|
||
'content_after' => '',
|
||
'content_layout' => '',
|
||
'content_show_bg' => '',
|
||
'list_style' => '',
|
||
];
|
||
|
||
$result = [];
|
||
foreach ($defaults as $key => $default) {
|
||
$meta_key = "shop_cat_{$key}";
|
||
$val = get_term_meta($term_id, $meta_key, true);
|
||
$result[$key] = ($val !== '' && $val !== false) ? $val : $default;
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Get all shop term meta for a product tag.
|
||
*
|
||
* @param int $term_id
|
||
* @return array
|
||
*/
|
||
public static function get_tag_meta(int $term_id): array {
|
||
$priority = get_term_meta($term_id, 'shop_tag_priority', true);
|
||
$class = get_term_meta($term_id, 'shop_tag_class', true);
|
||
$is_important = get_term_meta($term_id, 'shop_tag_is_important', true);
|
||
|
||
return [
|
||
'priority' => $priority !== '' ? (int) $priority : 0,
|
||
'class' => is_string($class) ? $class : '',
|
||
'is_important' => !empty($is_important),
|
||
];
|
||
}
|
||
|
||
/**
|
||
* Get all shop discount term meta.
|
||
*
|
||
* @param int $term_id
|
||
* @return array
|
||
*/
|
||
public static function get_discount_meta(int $term_id): array {
|
||
$defaults = [
|
||
'small_badge' => '',
|
||
'priority' => 0,
|
||
'is_important' => false,
|
||
'important_class' => '',
|
||
'scope' => 'item',
|
||
'type' => 'reduction',
|
||
'value' => '0',
|
||
'gift_config' => '',
|
||
'price_limit' => '0',
|
||
'user_limit' => '',
|
||
'start' => '',
|
||
'end' => '',
|
||
'countdown' => '',
|
||
];
|
||
|
||
$result = [];
|
||
foreach ($defaults as $key => $default) {
|
||
$meta_key = "shop_discount_{$key}";
|
||
$val = get_term_meta($term_id, $meta_key, true);
|
||
$result[$key] = ($val !== '' && $val !== false) ? $val : $default;
|
||
}
|
||
|
||
$result['priority'] = (int) $result['priority'];
|
||
$result['is_important'] = !empty($result['is_important']);
|
||
$result['price_limit'] = (float) $result['price_limit'];
|
||
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Resolve parameter inheritance: product → category → theme settings.
|
||
*
|
||
* Returns the effective value for a given parameter key by checking:
|
||
* 1. Product-level override (from post meta)
|
||
* 2. Category-level override (from term meta)
|
||
* 3. Theme-level default (from AKSRT_Settings::get_shop_settings())
|
||
*
|
||
* @param int $product_id Product post ID
|
||
* @param string $param_key Parameter key (e.g. 'limit_buy', 'shipping_fee')
|
||
* @param mixed $product_value Product-level value (null if not set)
|
||
* @return mixed
|
||
*/
|
||
public static function resolve_inheritance(int $product_id, string $param_key, $product_value = null) {
|
||
// 1. Product-level override
|
||
if ($product_value !== null && $product_value !== '' && $product_value !== -1) {
|
||
return $product_value;
|
||
}
|
||
|
||
// 2. Category-level override
|
||
$terms = get_the_terms($product_id, 'aksrt_product_cat');
|
||
if (is_array($terms) && !empty($terms)) {
|
||
$cat_meta_key = "shop_cat_{$param_key}";
|
||
foreach ($terms as $term) {
|
||
$val = get_term_meta($term->term_id, $cat_meta_key, true);
|
||
if ($val !== '' && $val !== false && $val !== -1) {
|
||
return $val;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 3. Theme-level default
|
||
$shop = AKSRT_Settings::get_shop_settings();
|
||
$defaults = $shop['product_defaults'] ?? [];
|
||
return $defaults[$param_key] ?? $product_value;
|
||
}
|
||
|
||
/**
|
||
* Add form fields for shop_discount taxonomy.
|
||
*/
|
||
public function render_discount_add_fields(): void {
|
||
$fields = $this->get_discount_field_definitions();
|
||
foreach ($fields as $key => $def) {
|
||
$label = (string) ($def['description'] ?? $key);
|
||
$default = $def['default'] ?? '';
|
||
echo '<div class="form-field">';
|
||
echo '<label for="' . esc_attr($key) . '">' . esc_html($label) . '</label>';
|
||
$this->render_discount_field_control($key, $default, false);
|
||
echo '</div>';
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Edit form fields for shop_discount taxonomy.
|
||
*/
|
||
public function render_discount_edit_fields($term): void {
|
||
if (!($term instanceof WP_Term)) {
|
||
return;
|
||
}
|
||
$fields = $this->get_discount_field_definitions();
|
||
foreach ($fields as $key => $def) {
|
||
$label = (string) ($def['description'] ?? $key);
|
||
$value = get_term_meta($term->term_id, $key, true);
|
||
if ($value === '' || $value === false) {
|
||
$value = $def['default'] ?? '';
|
||
}
|
||
echo '<tr class="form-field">';
|
||
echo '<th scope="row"><label for="' . esc_attr($key) . '">' . esc_html($label) . '</label></th>';
|
||
echo '<td>';
|
||
$this->render_discount_field_control($key, $value, true);
|
||
echo '</td></tr>';
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @param string|int|float $value
|
||
*/
|
||
private function render_discount_field_control(string $key, $value, bool $edit): void {
|
||
$id = esc_attr($key);
|
||
$name = esc_attr($key);
|
||
$val = (string) $value;
|
||
|
||
if ($key === 'shop_discount_type') {
|
||
$opts = [
|
||
'reduction' => __('立减', 'aksrt'),
|
||
'discount' => __('折扣', 'aksrt'),
|
||
'gift' => __('赠品', 'aksrt'),
|
||
];
|
||
echo '<select name="' . $name . '" id="' . $id . '">';
|
||
foreach ($opts as $k => $label) {
|
||
printf('<option value="%s"%s>%s</option>', esc_attr($k), selected($val, $k, false), esc_html($label));
|
||
}
|
||
echo '</select>';
|
||
return;
|
||
}
|
||
|
||
if ($key === 'shop_discount_scope') {
|
||
$opts = [
|
||
'item' => __('单品', 'aksrt'),
|
||
'product' => __('商品', 'aksrt'),
|
||
'author' => __('商家', 'aksrt'),
|
||
'order' => __('整单', 'aksrt'),
|
||
];
|
||
echo '<select name="' . $name . '" id="' . $id . '">';
|
||
foreach ($opts as $k => $label) {
|
||
printf('<option value="%s"%s>%s</option>', esc_attr($k), selected($val, $k, false), esc_html($label));
|
||
}
|
||
echo '</select>';
|
||
return;
|
||
}
|
||
|
||
if ($key === 'shop_discount_user_limit') {
|
||
$opts = [
|
||
'' => __('不限', 'aksrt'),
|
||
'vip' => __('VIP1', 'aksrt'),
|
||
'vip_2' => __('VIP2', 'aksrt'),
|
||
'auth' => __('已认证', 'aksrt'),
|
||
];
|
||
echo '<select name="' . $name . '" id="' . $id . '">';
|
||
foreach ($opts as $k => $label) {
|
||
printf('<option value="%s"%s>%s</option>', esc_attr($k), selected($val, $k, false), esc_html($label));
|
||
}
|
||
echo '</select>';
|
||
return;
|
||
}
|
||
|
||
if (in_array($key, ['shop_discount_is_important', 'shop_discount_countdown'], true)) {
|
||
echo '<label><input type="checkbox" name="' . $name . '" id="' . $id . '" value="1" ' . checked($val, '1', false) . '> ' . esc_html__('启用', 'aksrt') . '</label>';
|
||
return;
|
||
}
|
||
|
||
if ($key === 'shop_discount_gift_config') {
|
||
echo '<textarea name="' . $name . '" id="' . $id . '" rows="3" class="large-text">' . esc_textarea($val) . '</textarea>';
|
||
return;
|
||
}
|
||
|
||
$type = in_array($key, ['shop_discount_priority'], true) ? 'number' : 'text';
|
||
if (in_array($key, ['shop_discount_start', 'shop_discount_end'], true)) {
|
||
$type = 'datetime-local';
|
||
// Convert mysql-ish values to datetime-local if needed.
|
||
if ($val !== '' && str_contains($val, ' ')) {
|
||
$val = str_replace(' ', 'T', substr($val, 0, 16));
|
||
}
|
||
}
|
||
|
||
printf(
|
||
'<input type="%s" name="%s" id="%s" value="%s" class="%s" />',
|
||
esc_attr($type),
|
||
$name,
|
||
$id,
|
||
esc_attr($val),
|
||
$edit ? 'regular-text' : ''
|
||
);
|
||
}
|
||
|
||
public function save_discount_term_fields(int $term_id): void {
|
||
if (!current_user_can('manage_categories')) {
|
||
return;
|
||
}
|
||
|
||
$fields = $this->get_discount_field_definitions();
|
||
foreach ($fields as $key => $def) {
|
||
if (in_array($key, ['shop_discount_is_important', 'shop_discount_countdown'], true)) {
|
||
$raw = isset($_POST[$key]) ? '1' : '';
|
||
} else {
|
||
if (!isset($_POST[$key])) {
|
||
continue;
|
||
}
|
||
$raw = wp_unslash($_POST[$key]);
|
||
}
|
||
|
||
if (isset($def['sanitize']) && is_callable($def['sanitize'])) {
|
||
$value = call_user_func($def['sanitize'], $raw);
|
||
} else {
|
||
$value = sanitize_text_field((string) $raw);
|
||
}
|
||
|
||
if (in_array($key, ['shop_discount_start', 'shop_discount_end'], true) && is_string($value) && str_contains($value, 'T')) {
|
||
$value = str_replace('T', ' ', $value);
|
||
if (strlen($value) === 16) {
|
||
$value .= ':00';
|
||
}
|
||
}
|
||
|
||
update_term_meta($term_id, $key, $value);
|
||
}
|
||
}
|
||
|
||
public function render_cat_add_fields(): void {
|
||
foreach ($this->get_cat_field_definitions() as $key => $def) {
|
||
echo '<div class="form-field">';
|
||
echo '<label for="' . esc_attr($key) . '">' . esc_html((string) ($def['description'] ?? $key)) . '</label>';
|
||
$this->render_cat_field_control($key, $def['default'] ?? '', false);
|
||
echo '</div>';
|
||
}
|
||
}
|
||
|
||
public function render_cat_edit_fields($term): void {
|
||
if (!($term instanceof WP_Term)) {
|
||
return;
|
||
}
|
||
foreach ($this->get_cat_field_definitions() as $key => $def) {
|
||
$value = get_term_meta($term->term_id, $key, true);
|
||
if ($value === '' || $value === false) {
|
||
$value = $def['default'] ?? '';
|
||
}
|
||
echo '<tr class="form-field"><th scope="row"><label for="' . esc_attr($key) . '">' . esc_html((string) ($def['description'] ?? $key)) . '</label></th><td>';
|
||
$this->render_cat_field_control($key, $value, true);
|
||
echo '</td></tr>';
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @param mixed $value
|
||
*/
|
||
private function render_cat_field_control(string $key, $value, bool $edit): void {
|
||
$val = (string) $value;
|
||
if (in_array($key, ['shop_cat_guest_buy', 'shop_cat_email_fill', 'shop_cat_content_show_bg'], true)) {
|
||
echo '<label><input type="checkbox" name="' . esc_attr($key) . '" value="1" ' . checked($val, '1', false) . '> ' . esc_html__('启用', 'aksrt') . '</label>';
|
||
return;
|
||
}
|
||
if (in_array($key, ['shop_cat_service', 'shop_cat_single_tab', 'shop_cat_content_after'], true)) {
|
||
echo '<textarea class="large-text" rows="3" name="' . esc_attr($key) . '" id="' . esc_attr($key) . '">' . esc_textarea($val) . '</textarea>';
|
||
return;
|
||
}
|
||
if ($key === 'shop_cat_shipping_fee') {
|
||
$opts = ['' => __('继承', 'aksrt'), 'free' => __('包邮', 'aksrt'), 'fixed' => __('固定运费', 'aksrt'), 'amount' => __('满额包邮', 'aksrt')];
|
||
echo '<select name="' . esc_attr($key) . '" id="' . esc_attr($key) . '">';
|
||
foreach ($opts as $k => $label) {
|
||
printf('<option value="%s"%s>%s</option>', esc_attr($k), selected($val, $k, false), esc_html($label));
|
||
}
|
||
echo '</select>';
|
||
return;
|
||
}
|
||
if ($key === 'shop_cat_after_sale') {
|
||
$opts = ['' => __('继承', 'aksrt'), 'refund' => __('仅退款', 'aksrt'), 'refund_return' => __('退货退款', 'aksrt'), 'none' => __('不支持', 'aksrt')];
|
||
echo '<select name="' . esc_attr($key) . '" id="' . esc_attr($key) . '">';
|
||
foreach ($opts as $k => $label) {
|
||
printf('<option value="%s"%s>%s</option>', esc_attr($k), selected($val, $k, false), esc_html($label));
|
||
}
|
||
echo '</select>';
|
||
return;
|
||
}
|
||
if ($key === 'shop_cat_content_layout') {
|
||
$opts = ['' => __('继承', 'aksrt'), 'adapt' => __('自适应', 'aksrt'), 'full' => __('通栏', 'aksrt'), 'sidebar' => __('侧栏', 'aksrt')];
|
||
echo '<select name="' . esc_attr($key) . '" id="' . esc_attr($key) . '">';
|
||
foreach ($opts as $k => $label) {
|
||
printf('<option value="%s"%s>%s</option>', esc_attr($k), selected($val, $k, false), esc_html($label));
|
||
}
|
||
echo '</select>';
|
||
return;
|
||
}
|
||
if ($key === 'shop_cat_list_style') {
|
||
$opts = ['' => __('继承', 'aksrt'), 'default' => __('默认', 'aksrt'), 'card-lg' => __('大卡片', 'aksrt'), 'card-sm' => __('小卡片', 'aksrt')];
|
||
echo '<select name="' . esc_attr($key) . '" id="' . esc_attr($key) . '">';
|
||
foreach ($opts as $k => $label) {
|
||
printf('<option value="%s"%s>%s</option>', esc_attr($k), selected($val, $k, false), esc_html($label));
|
||
}
|
||
echo '</select>';
|
||
return;
|
||
}
|
||
$type = $key === 'shop_cat_limit_buy' ? 'number' : 'text';
|
||
printf(
|
||
'<input type="%s" class="%s" name="%s" id="%s" value="%s" />',
|
||
esc_attr($type),
|
||
$edit ? 'regular-text' : '',
|
||
esc_attr($key),
|
||
esc_attr($key),
|
||
esc_attr($val)
|
||
);
|
||
}
|
||
|
||
public function save_cat_term_fields(int $term_id): void {
|
||
if (!current_user_can('manage_categories')) {
|
||
return;
|
||
}
|
||
foreach ($this->get_cat_field_definitions() as $key => $def) {
|
||
if (in_array($key, ['shop_cat_guest_buy', 'shop_cat_email_fill', 'shop_cat_content_show_bg'], true)) {
|
||
$raw = isset($_POST[$key]) ? '1' : '';
|
||
} else {
|
||
if (!isset($_POST[$key])) {
|
||
continue;
|
||
}
|
||
$raw = wp_unslash($_POST[$key]);
|
||
}
|
||
if (isset($def['sanitize']) && is_callable($def['sanitize'])) {
|
||
$value = call_user_func($def['sanitize'], $raw);
|
||
} else {
|
||
$value = sanitize_text_field((string) $raw);
|
||
}
|
||
update_term_meta($term_id, $key, $value);
|
||
}
|
||
}
|
||
}
|