php - 如何在 WooCommerce 4+ 中为产品添加自定义库存状态

标签 php wordpress woocommerce hook-woocommerce stock

我正在使用以下代码在 WooCommerce 4.0 中添加新的库存状态。
新的状态是:

  • 预订
  • 联系我们

  • function add_custom_stock_type() {
        ?>
        <script type="text/javascript">
        jQuery(function(){
            jQuery('._stock_status_field').not('.custom-stock-status').remove();
        });
        </script>
    <?php   
    
        woocommerce_wp_select( array( 'id' => '_stock_status', 'wrapper_class' => 'custom-stock-status', 'label' => __( 'Stock status', 'woocommerce' ), 'options' => array(
            'instock'     => __( 'Available', 'woocommerce' ), //changed the name
            'outofstock'  => __( 'Sold out', 'woocommerce' ), //changed the name
            'onbackorder' => __( 'Preorder : Pending Distributor release', 'woocommerce' ), //changed the name
            'contact'     => __( 'Contact us for Availability', 'woocommerce' ), //added new one
            'preorder'    => __( 'On Preorder: Pending Distributor release', 'woocommerce' ), //added new one
        ), 'desc_tip' => true, 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ) ) );
    }
    add_action('woocommerce_product_options_stock_status', 'add_custom_stock_type');
    
    function save_custom_stock_status( $product_id ) {
        update_post_meta( $product_id, '_stock_status', wc_clean( $_POST['_stock_status'] ) );
    }
    add_action('woocommerce_process_product_meta', 'save_custom_stock_status',99,1);
    
    function woo_add_custom_general_fields_save_two( $post_id ){
        // Select
        $woocommerce_select = $_POST['_stock_status'];
        if( !empty( $woocommerce_select ) )
            update_post_meta( $post_id, '_stock_status', esc_attr( $woocommerce_select ) );
        else
        update_post_meta( $post_id, '_stock_status', '' );
        }
    
    function woocommerce_get_custom_availability( $data, $product ) {
        switch( $product->stock_status ) {
            case 'instock':
                $data = array( 'availability' => __( 'Available', 'woocommerce' ), 'class' => 'in-stock' ); //changed name
            break;
            case 'outofstock':
                $data = array( 'availability' => __( 'Sold Out', 'woocommerce' ), 'class' => 'out-of-stock' ); //changed name
            break;
            case 'onbackorder':
                $data = array( 'availability' => __( 'Preorder : Pending Distributor release', 'woocommerce' ), 'class' => 'onbackorder' ); //changed name
            break;
            case 'contact':
                $data = array( 'availability' => __( 'Contact us for Availability', 'woocommerce' ), 'class' => 'contact' ); //added new one
            break;
            case 'preorder':
                $data = array( 'availability' => __( 'On Preorder : Pending Distributor release', 'woocommerce' ), 'class' => 'preorder' ); //added new one
            break;
        }
        return $data;
    }
    add_action('woocommerce_get_availability', 'woocommerce_get_custom_availability', 10, 4);
    

    作品:
  • 后端:下拉菜单中添加了新的状态,我可以选择我想要的状态。

  • 不起作用:
  • 前端:在单个产品页面上未显示正确状态。
  • 后端:在管理产品列表表上显示新状态

  • 有人可以帮助我吗?

    最佳答案

    最后更新:04/21 - 在 WordPress 5.7.1 和 WooCommerce 5.2.2 中测试

    Use woocommerce_product_stock_status_options

    instead of woocommerce_product_options_stock_status.

    This way you can immediately add a status instead of replace the existing dropdown



    Also use woocommerce_get_availability_text & woocommerce_get_availability_class opposite woocommerce_get_availability.

    This way you don't have to add the existing statuses again


    // Add new stock status options
    function filter_woocommerce_product_stock_status_options( $status ) {
        // Add new statuses
        $status['pre_order'] = __( 'Pre order', 'woocommerce' );
        $status['contact_us'] = __( 'Contact us', 'woocommerce' );
    
        return $status;
    }
    add_filter( 'woocommerce_product_stock_status_options', 'filter_woocommerce_product_stock_status_options', 10, 1 );
    
    // Availability text
    function filter_woocommerce_get_availability_text( $availability, $product ) {
        // Get stock status
        switch( $product->get_stock_status() ) {
            case 'pre_order':
                $availability = __( 'Pre order', 'woocommerce' );
            break;
            case 'contact_us':
                $availability = __( 'Contact us', 'woocommerce' );
            break;
        }
    
        return $availability; 
    }
    add_filter( 'woocommerce_get_availability_text', 'filter_woocommerce_get_availability_text', 10, 2 );
    
    // Availability CSS class
    function filter_woocommerce_get_availability_class( $class, $product ) {
        // Get stock status
        switch( $product->get_stock_status() ) {
            case 'pre_order':
                $class = 'pre-order';
            break;
            case 'contact_us':
                $class = 'contact-us';
            break;
        }
    
        return $class;
    }
    add_filter( 'woocommerce_get_availability_class', 'filter_woocommerce_get_availability_class', 10, 2 );
    

    enter image description here

    Use woocommerce_admin_stock_html to display the new stock status on the admin products list table


    // Admin stock html
    function filter_woocommerce_admin_stock_html( $stock_html, $product ) {
        // Simple
        if ( $product->is_type( 'simple' ) ) {
            // Get stock status
            $product_stock_status = $product->get_stock_status();
        // Variable
        } elseif ( $product->is_type( 'variable' ) ) {
            foreach( $product->get_visible_children() as $variation_id ) {
                // Get product
                $variation = wc_get_product( $variation_id );
                
                // Get stock status
                $product_stock_status = $variation->get_stock_status();
                
                /*
                Currently the status of the last variant in the loop will be displayed.
                
                So from here you need to add your own logic, depending on what you expect from your custom stock status.
                
                By default, for the existing statuses. The status displayed on the admin products list table for variable products is determined as:
                
                - Product should be in stock if a child is in stock.
                - Product should be out of stock if all children are out of stock.
                - Product should be on backorder if all children are on backorder.
                - Product should be on backorder if at least one child is on backorder and the rest are out of stock.
                */
            }
        }
        
        // Stock status
        switch( $product_stock_status ) {
            case 'pre_order':
                $stock_html = '<mark class="pre-order" style="background:transparent none;color:#33ccff;font-weight:700;line-height:1;">' . __( 'Pre order', 'woocommerce' ) . '</mark>';
            break;
            case 'contact_us':
                $stock_html = '<mark class="contact-us" style="background:transparent none;color:#cc33ff;font-weight:700;line-height:1;">' . __( 'Contact us', 'woocommerce' ) . '</mark>';
            break;
        }
     
        return $stock_html;
    }
    add_filter( 'woocommerce_admin_stock_html', 'filter_woocommerce_admin_stock_html', 10, 2 );
    
    enter image description here

    如果需要,自定义库存状态可以用于您已经可以访问 $product 的 Hook 中。对象或您使用 global $product .
    // An example based on global $product
    // Get the global product object
    global $product;
    
    // Is a WC product
    if ( is_a( $product, 'WC_Product' ) ) {
        // Get stock status
        $product_stock_status = $product->get_stock_status();
        
        // Compare
        if ( $product_stock_status == 'My custom stock status' ) {
            // Etc..
        }
    }
    

    关于php - 如何在 WooCommerce 4+ 中为产品添加自定义库存状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61796640/

    相关文章:

    javascript - Ajax,多个下拉菜单

    wordpress - 有没有办法从WordPress插件中以编程方式启用小部件?

    PHP WordPress Textarea 小部件保存将文本移到 Textarea 之外

    css - WooCommerce 购物车和结帐布局问题

    php - MySQL 如何在 PHP 变量中存储 FOUND_ROWS()

    javascript - 登录google plus api后如何获取用户数据?

    数组中的 PHP 字符串只返回第一个字符

    wordpress - Paypal 自适应支付插件不适用于 WooCommerce

    php - 在 Woocommerce 结帐页面中移动付款方式

    wordpress - 德语特殊字符在 WordPress 架构中不起作用