You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DOKAN多商户平台自动生成商品SKU问题求助

问题:Dokan商户后台无法自动生成SKU(管理员后台正常)

我在WooCommerce中安装了Dokan多商户插件,同时配置了自动生成SKU的插件。该插件在管理员创建商品时可正常生成SKU,但商户通过Dokan商户后台创建商品时无法生成SKU。经确认,Dokan的SKU输入字段名称与默认WooCommerce的SKU字段名称一致,字段代码如下:

<input type="text" name="_sku" id="_sku" value="" class="dokan-form-control" placeholder="">

我拥有一套可在WooCommerce管理员后台正常运行的SKU生成代码,代码如下:

<?php
/**
 * Plugin Name: WooCommerce Product SKU Generator
 * Plugin URI: http://www.skyverge.com/product/woocommerce-product-sku-generator/
 * Description: Automatically generate SKUs for products using the product slug and (optionally) variation attributes
 * Author: SkyVerge
 * Author URI: http://www.skyverge.com/
 * Version: 1.2.2
 * Text Domain: wc-product-sku-generator
 * Domain Path: /i18n/languages/
 *
 * Copyright: (c) 2012-2015 SkyVerge, Inc. (info@skyverge.com)
 *
 * License: GNU General Public License v3.0
 * License URI: http://www.gnu.org/licenses/gpl-3.0.html
 *
 * @package   WC-Product-SKU-Generator
 * @author    SkyVerge
 * @category  Admin
 * @copyright Copyright (c) 2012-2015, SkyVerge, Inc.
 * @license   http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
 *
 */

 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

/**
 * Plugin Description
 *
 * Generate a SKU for new products that is equal to the product slug (simple products).
 * Optionally append attributes for a product variation to this if the product is variable.
 * Or, set a SKU for a parent product and optionally append attributes to this for variation SKUs.
 *
 * For example, if parent SKUs are generated, a product with the slug 'wp-tee-shirt'
 * will have a SKU of 'wp-tee-shirt'. If variation SKUs are also generated, this SKU will
 * be used, and attributes will be appended. For a white tee shirt in small, the SKU will
 * be 'wp-tee-shirt-small-white'. If only variation SKUs are generated, then the parent SKU
 * will be set and used, and attributes will be appended to it.
 */
 
/**
 * Load Translations
 *
 * @since 1.2.1
 */
function wc_sku_generator_load_translation() {
    // localization
    load_plugin_textdomain( 'wc-product-sku-generator', false, dirname( plugin_basename( __FILE__ ) ) . '/i18n/languages' );
}
add_action( 'init', 'wc_sku_generator_load_translation' );

/**
 * Update product SKUs using the generated SKU
 *
 * @since 1.0
 */
function wc_sku_generator_update_product( $post_id, $post ) {

    $product = get_product( $post_id );

    wc_sku_generator_update_sku( $product );

}
add_action( 'woocommerce_process_product_meta', 'wc_sku_generator_update_product', 100, 2 );


/**
 * Generate a product SKU from the product slug and/or variation attributes
 *
 * @since 1.0
 */
function wc_sku_generator_update_sku( $product ) {

    $generate_skus = get_option( 'wc_sku_generator_select', 'all' );

    // Only generate SKUs for product variations if enabled
    if ( 'all' == $generate_skus ) {
    
        $sku = apply_filters( 'wc_sku_generator_sku', $product->get_post_data()->post_name, $product );

        if ( $product->is_type( 'variable' ) ) {

            foreach( $product->get_available_variations() as $variation ) {

                $variation_sku = implode( $variation['attributes'], '-' );
                $variation_sku = str_replace( 'attribute_', '', $variation_sku );

                update_post_meta( $variation['variation_id'], '_sku', $sku . '-' . $variation_sku );

            }

            update_post_meta( $product->id, '_sku', $sku );

        } else {

            update_post_meta( $product->id, '_sku', $sku );
        }

    } elseif ( 'simple' == $generate_skus ) {
    
        $sku = apply_filters( 'wc_sku_generator_sku', $product->get_post_data()->post_name, $product );

        update_post_meta( $product->id, '_sku', $sku );

    } else {
        $sku = $product->get_sku();

        if ( $product->is_type( 'variable' ) ) {

            foreach ( $product->get_available_variations() as $variation ) {

                $variation_sku = implode( $variation['attributes'], '-' );
                $variation_sku = str_replace( 'attribute_', '', $variation_sku );

                update_post_meta( $variation['variation_id'], '_sku', $sku . '-' . $variation_sku );

            }

            update_post_meta( $product->id, '_sku', $sku );

        }
    }

}
add_action( 'woocommerce_product_bulk_edit_save', 'wc_sku_generator_update_sku');


/**
 * Only disable SKU field if parent SKUs are being generated
 *
 * @since 1.0.2
 */
$sku_settings = get_option( 'wc_sku_generator_select', 'all' );

if ( $sku_settings !== 'variations' ) {

    //Disable SKUs temporarily so we can create our own label
    function wc_sku_generator_disable_sku_input() {
        add_filter( 'wc_product_sku_enabled', '__return_false' );
    }
    add_action( 'woocommerce_product_write_panel_tabs', 'wc_sku_generator_disable_sku_input' );

    //Create a custom SKU label for Product Data
    function wc_sku_generator_create_sku_label() {
        global $thepostid;

        ?><p class="form-field"><label><?php esc_html_e( 'SKU', 'wc-product-sku-generator' ); ?></label><span><?php echo esc_html( get_post_meta( $thepostid, '_sku', true ) ); ?></span></p><?php

        add_filter( 'wc_product_sku_enabled', '__return_true' );
    }
    add_action( 'woocommerce_product_options_sku', 'wc_sku_generator_create_sku_label' );
}


/**
 * Add SKU generator to Settings > Products page at the end of the 'Product Data' section
 * 
 * @since 1.0
 */
function wc_sku_generator_add_settings( $settings ) {
    
    $updated_settings = array();
    
    $is_gte_wc_2_3 = version_compare( WC_VERSION, '2.3', '>=' );
    
    $setting_id = $is_gte_wc_2_3 ? 'product_measurement_options' : 'woocommerce_dimension_unit';
    $setting_type = $is_gte_wc_2_3 ? 'sectionend' : 'select';
    
    foreach ( $settings as $setting ) {

        $updated_settings[] = $setting;

        if ( isset( $setting['id'] ) && $setting_id === $setting['id'] && $setting_type === $setting['type'] ) {

            if ( $is_gte_wc_2_3 ) {
            
                $updated_settings[] = array(
                    'title'     => __( 'SKUs', 'wc-product-sku-generator' ),
                    'type'      => 'title',
                    'id'        => 'product_sku_options'
                );
                
                $updated_settings[] = wc_sku_generator_get_setting();
                
                $updated_settings[] = array(
                    'type'  => 'sectionend',
                    'id'    => 'product_sku_options'
                );
                
            } else {
                
                $updated_settings[] = wc_sku_generator_get_setting();
            }
            
        }
    }
    
    return $updated_settings;
}
add_filter( 'woocommerce_products_general_settings', 'wc_sku_generator_add_settings' );
add_filter( 'woocommerce_product_settings', 'wc_sku_generator_add_settings' );


/**
 * Create SKU Generator settings
 *
 * @since 1.2
 */
function wc_sku_generator_get_setting() {

    return array(

                'title'    => __( 'Generate SKUs for:', 'wc-product-sku-generator' ),
                'desc'     => '<br/>' . __( 'Should SKUs be generated for simple/parent products only, variations only, or both?', 'wc-product-sku-generator' ),
                'id'       => 'wc_sku_generator_select',
                'type'     => 'select',
                'options'  => array(
                    'all'        => __( 'Both parent products and variations', 'wc-product-sku-generator' ),
                    'simple'     => __( 'Only for simple or parent products', 'wc-product-sku-generator' ),
                    'variations' => __( 'Only for variations of the product', 'wc-product-sku-generator' ),
                ),
                'default'  => 'all',
                'class'    => 'wc-enhanced-select chosen_select',
                'css'      => 'min-width:300px;',
                'desc_tip' => __( 'Choosing "Only variations" will allow you to set a parent SKU. The SKU field is disabled otherwise.', 'wc-product-sku-generator' ),

    );
}

Dokan商户后台截图:
Dokan商户后台截图


解决建议

  • 适配Dokan专属钩子:原SKU生成代码仅监听WooCommerce管理员后台的woocommerce_process_product_meta钩子,而Dokan商户后台保存商品时使用dokan_new_product_added(新增商品)和dokan_product_updated(更新商品)钩子。在原代码中添加以下代码,让SKU生成逻辑覆盖Dokan场景:
    // 适配Dokan商户后台商品保存事件
    add_action( 'dokan_new_product_added', 'wc_sku_generator_update_product_via_dokan', 100, 1 );
    add_action( 'dokan_product_updated', 'wc_sku_generator_update_product_via_dokan', 100, 1 );
    
    function wc_sku_generator_update_product_via_dokan( $post_id ) {
        $product = wc_get_product( $post_id ); // 替换旧版get_product(),兼容新WooCommerce版本
        if ( $product ) {
            wc_sku_generator_update_sku( $product );
        }
    }
    
  • 替换旧版函数:原代码中get_product()是WooCommerce旧版函数,全局替换为wc_get_product(),避免兼容性问题。
  • 修复SKU字段控制逻辑:原代码中禁用SKU输入的逻辑会影响Dokan商户后台,添加is_admin()条件,仅在管理员后台执行该逻辑:
    // 修改原代码中的判断条件
    if ( $sku_settings !== 'variations' && is_admin() ) {
        // 原禁用SKU输入和创建自定义标签的代码保留
    }
    
  • 调试钩子执行状态:开启WP_DEBUG后,在wc_sku_generator_update_product函数中添加日志,确认Dokan保存时是否触发了该函数:
    function wc_sku_generator_update_product( $post_id, $post ) {
        error_log( 'SKU Generator triggered for post ID: ' . $post_id ); // 日志写入wp-content/debug.log
        $product = wc_get_product( $post_id );
        wc_sku_generator_update_sku( $product );
    }
    
  • 检查商户权限:确认Dokan商户角色拥有edit_posts和edit_products权限,确保能正常写入商品元数据。

内容的提问来源于stack exchange,提问作者Geofrey Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 21:19:51