feat(admin): native plate moderators, product variants, discount term fields
Add WP-native ops UI without SPA: plate moderator list/application review meta box, product SKU variants editor meta box, and shop_discount taxonomy add/edit form fields. No admin build artifacts included.
This commit is contained in:
@@ -298,6 +298,16 @@ if (is_admin() && class_exists('AKSRT_Admin_Shop_Controller')) {
|
||||
if (is_admin() && class_exists('AKSRT_Product_Meta_Box')) {
|
||||
AKSRT_Product_Meta_Box::get_instance()->init();
|
||||
}
|
||||
// 商品原生变体 meta box
|
||||
if (is_admin() && class_exists('AKSRT_Product_Variants_Meta_Box')) {
|
||||
AKSRT_Product_Variants_Meta_Box::get_instance()->init();
|
||||
}
|
||||
|
||||
// 论坛版块版主 meta box
|
||||
if (is_admin() && class_exists('AKSRT_Plate_Meta_Box')) {
|
||||
AKSRT_Plate_Meta_Box::get_instance()->init();
|
||||
}
|
||||
|
||||
|
||||
// 商品评价/评分系统
|
||||
if (class_exists('AKSRT_Product_Review')) {
|
||||
|
||||
@@ -321,6 +321,8 @@ require_once AKSRT_DIR . '/inc/classes/shop/class-aksrt-shop-checkout-service.ph
|
||||
require_once AKSRT_DIR . '/inc/classes/shop/class-aksrt-shop-address-service.php';
|
||||
require_once AKSRT_DIR . '/inc/classes/shop/class-aksrt-shop-product-service.php';
|
||||
require_once AKSRT_DIR . '/inc/classes/shop/class-aksrt-product-meta-box.php';
|
||||
require_once AKSRT_DIR . '/inc/classes/shop/class-aksrt-product-variants-meta-box.php';
|
||||
require_once AKSRT_DIR . '/inc/classes/forum/class-aksrt-plate-meta-box.php';
|
||||
require_once AKSRT_DIR . '/inc/classes/shop/shop-traits/trait-aksrt-shop-part-1.php';
|
||||
require_once AKSRT_DIR . '/inc/classes/shop/shop-traits/trait-aksrt-shop-part-2.php';
|
||||
require_once AKSRT_DIR . '/inc/classes/shop/shop-traits/trait-aksrt-shop-part-3.php';
|
||||
|
||||
@@ -33,6 +33,12 @@ class AKSRT_Shop_Term_Meta {
|
||||
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']);
|
||||
}
|
||||
|
||||
// ─── Taxonomy Registration ───────────────────────────────────
|
||||
@@ -408,4 +414,155 @@ class AKSRT_Shop_Term_Meta {
|
||||
$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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/**
|
||||
* Native meta box for aksrt_forum_plate moderators & applications.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class AKSRT_Plate_Meta_Box {
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance(): self {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function init(): void {
|
||||
if (!is_admin()) {
|
||||
return;
|
||||
}
|
||||
add_action('add_meta_boxes', [$this, 'register_meta_box']);
|
||||
add_action('save_post_aksrt_forum_plate', [$this, 'save'], 20, 2);
|
||||
}
|
||||
|
||||
public function register_meta_box(): void {
|
||||
add_meta_box(
|
||||
'aksrt_plate_moderators',
|
||||
__('版主与申请', 'aksrt'),
|
||||
[$this, 'render'],
|
||||
'aksrt_forum_plate',
|
||||
'side',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
|
||||
public function render(WP_Post $post): void {
|
||||
wp_nonce_field('aksrt_plate_meta_save', 'aksrt_plate_meta_nonce');
|
||||
|
||||
$moderator_ids = [];
|
||||
$applications = [];
|
||||
if (class_exists('AKSRT_Forum')) {
|
||||
$forum = AKSRT_Forum::get_instance();
|
||||
$moderator_ids = $forum->get_plate_moderators((int) $post->ID);
|
||||
$applications = $forum->get_plate_moderator_applications((int) $post->ID);
|
||||
} else {
|
||||
$raw = get_post_meta($post->ID, '_aksrt_moderators', true);
|
||||
$moderator_ids = is_array($raw) ? array_map('intval', $raw) : [];
|
||||
$applications = get_post_meta($post->ID, '_aksrt_moderator_applications', true);
|
||||
$applications = is_array($applications) ? $applications : [];
|
||||
}
|
||||
|
||||
$moderator_labels = [];
|
||||
foreach ($moderator_ids as $uid) {
|
||||
$user = get_userdata((int) $uid);
|
||||
$moderator_labels[] = $user
|
||||
? sprintf('%s (#%d)', $user->user_login, (int) $uid)
|
||||
: (string) (int) $uid;
|
||||
}
|
||||
?>
|
||||
<p>
|
||||
<label for="aksrt_plate_moderators"><strong><?php esc_html_e('版主用户 ID', 'aksrt'); ?></strong></label>
|
||||
<textarea id="aksrt_plate_moderators" name="aksrt_plate_moderators" rows="3" class="widefat" placeholder="1,2,3"><?php echo esc_textarea(implode(',', array_map('intval', $moderator_ids))); ?></textarea>
|
||||
<span class="description"><?php esc_html_e('逗号或换行分隔的用户 ID。超级版主为版块作者。', 'aksrt'); ?></span>
|
||||
</p>
|
||||
<?php if ($moderator_labels) : ?>
|
||||
<p class="description"><?php echo esc_html(implode(' · ', $moderator_labels)); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<hr>
|
||||
<p><strong><?php esc_html_e('版主申请', 'aksrt'); ?></strong></p>
|
||||
<?php
|
||||
$pending = array_values(array_filter($applications, static function ($app) {
|
||||
return is_array($app) && (($app['status'] ?? '') === 'pending' || ($app['status'] ?? '') === AKSRT_Forum::APPLICATION_PENDING);
|
||||
}));
|
||||
if (!$pending) {
|
||||
echo '<p class="description">' . esc_html__('暂无待处理申请。', 'aksrt') . '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
echo '<ul style="margin:0;padding-left:16px;">';
|
||||
foreach ($pending as $app) {
|
||||
$uid = (int) ($app['user_id'] ?? 0);
|
||||
$user = $uid > 0 ? get_userdata($uid) : null;
|
||||
$aid = (string) ($app['id'] ?? '');
|
||||
$reason = (string) ($app['reason'] ?? '');
|
||||
echo '<li style="margin-bottom:10px;">';
|
||||
echo '<div><code>' . esc_html($user ? $user->display_name . ' (#' . $uid . ')' : (string) $uid) . '</code></div>';
|
||||
if ($reason !== '') {
|
||||
echo '<div class="description">' . esc_html($reason) . '</div>';
|
||||
}
|
||||
echo '<label style="display:block;margin-top:4px;"><input type="radio" name="aksrt_plate_app[' . esc_attr($aid) . ']" value="keep" checked> ' . esc_html__('保留', 'aksrt') . '</label>';
|
||||
echo '<label style="display:block;"><input type="radio" name="aksrt_plate_app[' . esc_attr($aid) . ']" value="approved"> ' . esc_html__('通过', 'aksrt') . '</label>';
|
||||
echo '<label style="display:block;"><input type="radio" name="aksrt_plate_app[' . esc_attr($aid) . ']" value="rejected"> ' . esc_html__('拒绝', 'aksrt') . '</label>';
|
||||
echo '</li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
|
||||
public function save(int $post_id, WP_Post $post): void {
|
||||
if (!isset($_POST['aksrt_plate_meta_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash((string) $_POST['aksrt_plate_meta_nonce'])), 'aksrt_plate_meta_save')) {
|
||||
return;
|
||||
}
|
||||
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
||||
return;
|
||||
}
|
||||
if ($post->post_type !== 'aksrt_forum_plate' || !current_user_can('edit_post', $post_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$raw = isset($_POST['aksrt_plate_moderators']) ? (string) wp_unslash($_POST['aksrt_plate_moderators']) : '';
|
||||
$ids = preg_split('/[\s,;]+/', $raw) ?: [];
|
||||
$ids = array_values(array_unique(array_filter(array_map('intval', $ids))));
|
||||
update_post_meta($post_id, '_aksrt_moderators', $ids);
|
||||
|
||||
$actions = isset($_POST['aksrt_plate_app']) && is_array($_POST['aksrt_plate_app'])
|
||||
? wp_unslash($_POST['aksrt_plate_app'])
|
||||
: [];
|
||||
if (!$actions || !class_exists('AKSRT_Forum')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$forum = AKSRT_Forum::get_instance();
|
||||
foreach ($actions as $application_id => $action) {
|
||||
$application_id = sanitize_text_field((string) $application_id);
|
||||
$action = sanitize_key((string) $action);
|
||||
if ($application_id === '' || $action === 'keep') {
|
||||
continue;
|
||||
}
|
||||
if ($action === 'approved') {
|
||||
$forum->review_moderator_application($application_id, AKSRT_Forum::APPLICATION_APPROVED, '', get_current_user_id());
|
||||
} elseif ($action === 'rejected') {
|
||||
$forum->review_moderator_application($application_id, AKSRT_Forum::APPLICATION_REJECTED, '', get_current_user_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
/**
|
||||
* Native SKU variants meta box for aksrt_product.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class AKSRT_Product_Variants_Meta_Box {
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance(): self {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function init(): void {
|
||||
if (!is_admin()) {
|
||||
return;
|
||||
}
|
||||
add_action('add_meta_boxes', [$this, 'register_meta_box']);
|
||||
add_action('save_post_aksrt_product', [$this, 'save'], 30, 2);
|
||||
}
|
||||
|
||||
public function register_meta_box(): void {
|
||||
add_meta_box(
|
||||
'aksrt_product_variants',
|
||||
__('SKU 变体', 'aksrt'),
|
||||
[$this, 'render'],
|
||||
'aksrt_product',
|
||||
'normal',
|
||||
'default'
|
||||
);
|
||||
}
|
||||
|
||||
public function render(WP_Post $post): void {
|
||||
wp_nonce_field('aksrt_product_variants_save', 'aksrt_product_variants_nonce');
|
||||
|
||||
$variants = [];
|
||||
if (class_exists('AKSRT_Shop')) {
|
||||
$variants = AKSRT_Shop::get_instance()->get_variants((int) $post->ID);
|
||||
}
|
||||
|
||||
if (!$variants) {
|
||||
$variants = [[
|
||||
'sku' => '',
|
||||
'attributes' => [],
|
||||
'price' => 0,
|
||||
'stock' => 0,
|
||||
'image' => '',
|
||||
]];
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
.aksrt-variants-table { width:100%; border-collapse:collapse; }
|
||||
.aksrt-variants-table th, .aksrt-variants-table td { border:1px solid #dcdcde; padding:6px; vertical-align:top; }
|
||||
.aksrt-variants-table input { width:100%; }
|
||||
.aksrt-variants-table .col-sku { width:14%; }
|
||||
.aksrt-variants-table .col-attrs { width:28%; }
|
||||
.aksrt-variants-table .col-price, .aksrt-variants-table .col-stock { width:12%; }
|
||||
.aksrt-variants-table .col-image { width:28%; }
|
||||
.aksrt-variants-hint { color:#646970; font-size:12px; margin:8px 0; }
|
||||
</style>
|
||||
<p class="aksrt-variants-hint">
|
||||
<?php esc_html_e('属性格式:名称:值,多项用分号分隔,例如 颜色:红;尺寸:L。保存时会整体覆盖该商品变体列表。', 'aksrt'); ?>
|
||||
</p>
|
||||
<table class="aksrt-variants-table" id="aksrt-variants-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sku"><?php esc_html_e('SKU', 'aksrt'); ?></th>
|
||||
<th class="col-attrs"><?php esc_html_e('属性', 'aksrt'); ?></th>
|
||||
<th class="col-price"><?php esc_html_e('价格', 'aksrt'); ?></th>
|
||||
<th class="col-stock"><?php esc_html_e('库存', 'aksrt'); ?></th>
|
||||
<th class="col-image"><?php esc_html_e('图片 URL', 'aksrt'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($variants as $i => $row) :
|
||||
$attrs = $row['attributes'] ?? [];
|
||||
$attrs_text = '';
|
||||
if (is_array($attrs)) {
|
||||
$parts = [];
|
||||
foreach ($attrs as $k => $v) {
|
||||
if (is_int($k) && is_array($v)) {
|
||||
$parts[] = ($v['name'] ?? $v['key'] ?? '') . ':' . ($v['value'] ?? '');
|
||||
} else {
|
||||
$parts[] = $k . ':' . $v;
|
||||
}
|
||||
}
|
||||
$attrs_text = implode(';', array_filter($parts));
|
||||
} elseif (is_string($attrs)) {
|
||||
$attrs_text = $attrs;
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td><input type="text" name="aksrt_variant_sku[]" value="<?php echo esc_attr((string) ($row['sku'] ?? '')); ?>"></td>
|
||||
<td><input type="text" name="aksrt_variant_attrs[]" value="<?php echo esc_attr($attrs_text); ?>" placeholder="颜色:红;尺寸:L"></td>
|
||||
<td><input type="number" step="0.01" min="0" name="aksrt_variant_price[]" value="<?php echo esc_attr((string) ($row['price'] ?? 0)); ?>"></td>
|
||||
<td><input type="number" step="1" min="0" name="aksrt_variant_stock[]" value="<?php echo esc_attr((string) ($row['stock'] ?? 0)); ?>"></td>
|
||||
<td><input type="url" name="aksrt_variant_image[]" value="<?php echo esc_attr((string) ($row['image'] ?? '')); ?>"></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>
|
||||
<button type="button" class="button" id="aksrt-add-variant-row"><?php esc_html_e('添加变体行', 'aksrt'); ?></button>
|
||||
</p>
|
||||
<script>
|
||||
(function(){
|
||||
var btn = document.getElementById('aksrt-add-variant-row');
|
||||
var tbody = document.querySelector('#aksrt-variants-table tbody');
|
||||
if (!btn || !tbody) return;
|
||||
btn.addEventListener('click', function(){
|
||||
var tr = document.createElement('tr');
|
||||
tr.innerHTML = '<td><input type="text" name="aksrt_variant_sku[]" value=""></td>' +
|
||||
'<td><input type="text" name="aksrt_variant_attrs[]" value="" placeholder="颜色:红;尺寸:L"></td>' +
|
||||
'<td><input type="number" step="0.01" min="0" name="aksrt_variant_price[]" value="0"></td>' +
|
||||
'<td><input type="number" step="1" min="0" name="aksrt_variant_stock[]" value="0"></td>' +
|
||||
'<td><input type="url" name="aksrt_variant_image[]" value=""></td>';
|
||||
tbody.appendChild(tr);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function save(int $post_id, WP_Post $post): void {
|
||||
if (!isset($_POST['aksrt_product_variants_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash((string) $_POST['aksrt_product_variants_nonce'])), 'aksrt_product_variants_save')) {
|
||||
return;
|
||||
}
|
||||
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
||||
return;
|
||||
}
|
||||
if ($post->post_type !== 'aksrt_product' || !current_user_can('edit_post', $post_id)) {
|
||||
return;
|
||||
}
|
||||
if (!class_exists('AKSRT_Shop')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$skus = isset($_POST['aksrt_variant_sku']) && is_array($_POST['aksrt_variant_sku']) ? wp_unslash($_POST['aksrt_variant_sku']) : [];
|
||||
$attrs = isset($_POST['aksrt_variant_attrs']) && is_array($_POST['aksrt_variant_attrs']) ? wp_unslash($_POST['aksrt_variant_attrs']) : [];
|
||||
$prices = isset($_POST['aksrt_variant_price']) && is_array($_POST['aksrt_variant_price']) ? wp_unslash($_POST['aksrt_variant_price']) : [];
|
||||
$stocks = isset($_POST['aksrt_variant_stock']) && is_array($_POST['aksrt_variant_stock']) ? wp_unslash($_POST['aksrt_variant_stock']) : [];
|
||||
$images = isset($_POST['aksrt_variant_image']) && is_array($_POST['aksrt_variant_image']) ? wp_unslash($_POST['aksrt_variant_image']) : [];
|
||||
|
||||
$variants = [];
|
||||
$count = max(count($skus), count($attrs), count($prices), count($stocks), count($images));
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$sku = sanitize_text_field((string) ($skus[$i] ?? ''));
|
||||
$attr_raw = sanitize_text_field((string) ($attrs[$i] ?? ''));
|
||||
$price = max(0, (float) ($prices[$i] ?? 0));
|
||||
$stock = max(0, (int) ($stocks[$i] ?? 0));
|
||||
$image = esc_url_raw((string) ($images[$i] ?? ''));
|
||||
|
||||
if ($sku === '' && $attr_raw === '' && $price <= 0 && $stock <= 0 && $image === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attributes = [];
|
||||
if ($attr_raw !== '') {
|
||||
foreach (preg_split('/\s*;\s*/', $attr_raw) ?: [] as $pair) {
|
||||
if ($pair === '' || !str_contains($pair, ':')) {
|
||||
continue;
|
||||
}
|
||||
[$k, $v] = array_map('trim', explode(':', $pair, 2));
|
||||
if ($k !== '') {
|
||||
$attributes[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$variants[] = [
|
||||
'sku' => $sku,
|
||||
'attributes' => $attributes,
|
||||
'price' => $price,
|
||||
'stock' => $stock,
|
||||
'image' => $image,
|
||||
];
|
||||
}
|
||||
|
||||
AKSRT_Shop::get_instance()->save_variants($post_id, $variants);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user