【问题标题】:Add custom fields as cart item meta and order item meta in WooCommerce在 WooCommerce 中将自定义字段添加为购物车项目元和订单项目元
【发布时间】:2018-05-31 14:31:00
【问题描述】:

这是一个关于如何为我的 WooCommerce 订单添加添加购物车项目元和订单项目元的插件。最初,我下面的代码对于输入类型 = 文本效果很好。它返回值的标签和输入的值。

在转换为 type=checkbox 时,代码返回 labelvalue="on" 用于检查的那些。

我想返回唯一的选中值的值名称(忽略未选中的值)。

帮助包含更多复选框选项的重构将有助于减少编写代码。

我的代码:

<?php
    global $woocommerce, $product, $post;

        add_action( 'woocommerce_before_add_to_cart_button', 'add_fields_before_add_to_cart' );

        function add_fields_before_add_to_cart( ) {
            ?>

            <div class="simple-selects">
                <div class="col-md-6">
                    <h3>Main meals</h3>
                    <p><input type="checkbox" name="mm_chicken_cutlet_bento" id="mm_chicken_cutlet_bento"><?php _e( "Chicken Cutlet Bento", "aoim"); ?></p>
                    <p><input type="checkbox" name="mm_roasted_pork_rib_bento" id="mm_roasted_pork_rib_bento"><?php _e( "Roasted Pork Rib Bento", "aoim"); ?></p>
                </div>
            </div>        

            <?php
        }

        /**
         * Add data to cart item
         */
        add_filter( 'woocommerce_add_cart_item_data', 'add_cart_item_data', 25, 2 );
        function add_cart_item_data( $cart_item_meta, $product_id ) {

            if ( isset( $_POST ['mm_chicken_cutlet_bento'] ) && isset( $_POST ['mm_roasted_pork_rib_bento'] ) ) {
                $custom_data  = array() ;
                $custom_data [ 'mm_chicken_cutlet_bento' ]    = isset( $_POST ['mm_chicken_cutlet_bento'] ) ?  sanitize_text_field ( $_POST ['mm_chicken_cutlet_bento'] ) : "" ;
                $custom_data [ 'mm_roasted_pork_rib_bento' ] = isset( $_POST ['mm_roasted_pork_rib_bento'] ) ? sanitize_text_field ( $_POST ['mm_roasted_pork_rib_bento'] ): "" ;
                $cart_item_meta ['custom_data']     = $custom_data ;
            }

            return $cart_item_meta;
        }

        /**
         * Display custom data on cart and checkout page.
         */
        add_filter( 'woocommerce_get_item_data', 'get_item_data' , 25, 2 );
        function get_item_data ( $other_data, $cart_item ) {
            if ( isset( $cart_item [ 'custom_data' ] ) ) {
                $custom_data  = $cart_item [ 'custom_data' ];

                $other_data[] = array( 'name' => 'Chicken Cutlet Bento', 'display'  => $custom_data['mm_chicken_cutlet_bento'] );
                $other_data[] = array( 'name' => 'Roasted Pork Rib Bento', 'display'  => $custom_data['mm_roasted_pork_rib_bento'] );
            }

            return $other_data;
        }

        /**
         * Add order item meta.
         */
        add_action( 'woocommerce_add_order_item_meta', 'add_order_item_meta' , 10, 2);
        function add_order_item_meta ( $item_id, $values ) {
            if ( isset( $values [ 'custom_data' ] ) ) {
                $custom_data  = $values [ 'custom_data' ];
                wc_add_order_item_meta( $item_id, 'Chicken Cutlet Bento', $custom_data['mm_chicken_cutlet_bento'] );
                wc_add_order_item_meta( $item_id, 'Roasted Pork Rib Bento', $custom_data['mm_roasted_pork_rib_bento'] );
            }
        }

?>

【问题讨论】:

    标签: php wordpress woocommerce cart custom-fields


    【解决方案1】:

    更新 (与cmets相关)

    • 功能仅限于一个产品 ID
    • 将所有复选框值添加为逗号分隔的字符串

    为了轻松将复选框的标签名称作为值并“重构以帮助包含更多复选框选项将有助于减少书面代码”,我添加了一个简单的函数,您可以在其中为每个复选框设置键/值对你想展示和处理……

    所以我重新审视了你所有的代码:

    // HERE set the array of pairs keys/values for your checkboxes
    function custom_checkboxes(){
        return array(
            'mm_chicken_cutlet_bento'       => __( "Chicken Cutlet Bento", "aoim"),
            'mm_roasted_pork_rib_bento'     => __( "Roasted Pork Rib Bento", "aoim"),
        );
    }
    
    // Displaying the checkboxes
    add_action( 'woocommerce_before_add_to_cart_button', 'add_fields_before_add_to_cart' );
    function add_fields_before_add_to_cart( ) {
        global $product;
        if( $product->get_id() != 2 ) return; // Only for product ID "2"
    
        ?>
        <div class="simple-selects">
            <div class="col-md-6">
                <h3><?php _e("Main meals", "aoim"); ?></h3>
                <?php foreach( custom_checkboxes() as $key => $value ): ?>
                    <p><input type="checkbox" name="<?php echo $key; ?>" id="<?php echo $key; ?>"><?php echo ' ' . $value; ?></p>
                <?php endforeach; ?>
            </div>
        </div>
        <?php
    }
    
    
    // Add data to cart item
    add_filter( 'woocommerce_add_cart_item_data', 'add_cart_item_data', 25, 2 );
    function add_cart_item_data( $cart_item_data, $product_id ) {
        if( $product_id != 2 ) return $cart_item_data; // Only for product ID "2"
    
        // Set the data for the cart item in cart object
        $data = array() ;
    
        foreach( custom_checkboxes() as $key => $value ){
            if( isset( $_POST[$key] ) )
                $cart_item_data['custom_data'][$key] = $data[$key] = $value;
        }
        // Add the data to session and generate a unique ID
        if( count($data > 0 ) ){
            $cart_item_data['custom_data']['unique_key'] = md5( microtime().rand() );
            WC()->session->set( 'custom_data', $data );
        }
        return $cart_item_data;
    }
    
    
    // Display custom data on cart and checkout page.
    add_filter( 'woocommerce_get_item_data', 'get_item_data' , 25, 2 );
    function get_item_data ( $cart_data, $cart_item ) {
        if( $cart_item['product_id'] != 2 ) return $cart_data; // Only for product ID "2"
    
        if( ! empty( $cart_item['custom_data'] ) ){
            $values =  array();
            foreach( $cart_item['custom_data'] as $key => $value )
                if( $key != 'unique_key' ){
                    $values[] = $value;
                }
            $values = implode( ', ', $values );
            $cart_data[] = array(
                'name'    => __( "Option", "aoim"),
                'display' => $values
            );
        }
    
        return $cart_data;
    }
    
    // Add order item meta.
    add_action( 'woocommerce_add_order_item_meta', 'add_order_item_meta' , 10, 3 );
    function add_order_item_meta ( $item_id, $cart_item, $cart_item_key ) {
        if ( isset( $cart_item[ 'custom_data' ] ) ) {
            $values =  array();
            foreach( $cart_item[ 'custom_data' ] as $key => $value )
                if( $key != 'unique_key' ){
                    $values[] = $value;
                }
            $values = implode( ', ', $values );
            wc_add_order_item_meta( $item_id, __( "Option", "aoim"), $values );
        }
    }
    

    此代码位于您的活动子主题(或主题)的 function.php 文件中或任何插件文件中。

    经过测试并且有效。


    你会得到这样的东西:

    我添加了“选项”作为标签以避免值重复......

    【讨论】:

    • 重构效果很好。有几个 tweeks 要添加。 1.这可以仅限于一个(仅)产品,比如具有特定ID的产品吗? 2. 我用图像更新了我的问题,以表明我的意思是“我想返回检查值的唯一值名称(忽略未检查的值)。”当它们只是逗号分隔时,我需要在结帐时在订单表中显示它们。
    • 例如,如果选中鸡排便当和烤猪排便当作为选项,它们应在订单表下列为“鸡排便当,烤猪排便当,示例 3,示例 4”我编辑这个问题用一张图片来说明我的意思。
    • @omukiguy 我已经为您的第一个请求更新了代码……仅针对一种产品进行了限制。
    • 我仍然迷失在你上面的评论中。也许我陷入了我的工作流程思想。理想情况下,我们会用逗号来呼应“炸鸡排便当,烤猪排便当”。无需改变结构。我对 php 数组不满意,但我们可以为此重构 add_filter( 'woocommerce_get_item_data', 'get_item_data' , 25, 2 ); 函数
    • @omukiguy 好吧,让我试试看……
    【解决方案2】:

    LoicTheAztec's solution 大部分情况下仍然有效,但现在已弃用将元数据从购物车添加到订单的操作。

    您可以像这样使用woocommerce_checkout_create_order_line_item 而不是woocommerce_add_order_item_meta(已弃用):

    add_action(
        'woocommerce_checkout_create_order_line_item',
        function(WC_Order_Item_Product $cartItem, string $cartItemKey, array $values): void {
            if (!empty($values['custom_data']) && is_array($values['custom_data'])) {
                $values = [];
                foreach ($values['custom_data'] as $key => $value) {
                    if ($key !== 'unique_key'){
                        $values[] = $value;
                    }
                }
                $cartItem->add_meta_data(__('Option', 'aoim'), implode(', ', $values), true);
            }
        },
        10,
        3
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-29
      • 2019-07-21
      • 2021-04-23
      • 2020-02-28
      • 2019-06-27
      • 1970-01-01
      • 1970-01-01
      • 2018-06-30
      相关资源
      最近更新 更多