在产品中添加自定义字段以显示在购物车、结帐和订单中

Posted

技术标签:

【中文标题】在产品中添加自定义字段以显示在购物车、结帐和订单中【英文标题】:Add custom field in products to display in cart, checkout and in orders 【发布时间】:2019-08-15 11:34:03 【问题描述】:

我正在使用自定义帖子类型并在其上集成了 woocommerce,我可以在页面上添加一个添加到购物车按钮并将其添加到购物车,所以它工作正常

这是我的代码

class WCCPT_Product_Data_Store_CPT extends WC_Product_Data_Store_CPT 

    /**
     * Method to read a product from the database.
     * @param WC_Product
     */

    public function read( &$product ) 

        $product->set_defaults();

        if ( ! $product->get_id() || ! ( $post_object = get_post( $product->get_id() ) ) || ! in_array( $post_object->post_type, array( 'products', 'product' ) ) )  // change birds with your post type
            throw new Exception( __( 'Invalid product.', 'woocommerce' ) );
        

        $id = $product->get_id();

        $product->set_props( array(
            'name'              => $post_object->post_title,
            'slug'              => $post_object->post_name,
            'date_created'      => 0 < $post_object->post_date_gmt ? wc_string_to_timestamp( $post_object->post_date_gmt ) : null,
            'date_modified'     => 0 < $post_object->post_modified_gmt ? wc_string_to_timestamp( $post_object->post_modified_gmt ) : null,
            'status'            => $post_object->post_status,
            'description'       => $post_object->post_content,
            'short_description' => $post_object->post_excerpt,
            'parent_id'         => $post_object->post_parent,
            'menu_order'        => $post_object->menu_order,
            'reviews_allowed'   => 'open' === $post_object->comment_status,
        ) );

        $this->read_attributes( $product );
        $this->read_downloads( $product );
        $this->read_visibility( $product );
        $this->read_product_data( $product );
        $this->read_extra_data( $product );
        $product->set_object_read( true );
    

    /**
     * Get the product type based on product ID.
     *
     * @since 3.0.0
     * @param int $product_id
     * @return bool|string
     */
    public function get_product_type( $product_id ) 
        $post_type = get_post_type( $product_id );
        if ( 'product_variation' === $post_type ) 
            return 'variation';
         elseif ( in_array( $post_type, array( 'products', 'product' ) ) )  // change birds with your post type
            $terms = get_the_terms( $product_id, 'product_type' );
            return ! empty( $terms ) ? sanitize_title( current( $terms )->name ) : 'simple';
         else 
            return false;
        
    


add_filter( 'woocommerce_data_stores', 'woocommerce_data_stores' );

function woocommerce_data_stores ( $stores )       
    $stores['product'] = 'WCCPT_Product_Data_Store_CPT';
    return $stores;


add_filter('woocommerce_product_get_price', 'woocommerce_product_get_price', 10, 2 );
function woocommerce_product_get_price( $price, $product ) 

    $reflector = new \ReflectionClass($product);
    $classProperty = $reflector->getProperty('id');
    $classProperty->setAccessible(true);
    $vid_id = $classProperty->getValue($product);
    //$cpt_product_price = get_field('product_specifications', $vid_id);    
    $cpt_product_price = get_field('e-commerce', $vid_id);

    if ($product->get_id() == $vid_id) 
        $price = $cpt_product_price['global']['price'];
    

    return $price;


//add_filter('the_content','rei_add_to_cart_button', 20,1);
/*
function rei_add_to_cart_button($content)
    global $post;
    if ($post->post_type !== 'products') return $content; 
    var_dump($content);


    $cpt_product_price = get_field('product_specifications', get_the_ID());
    //var_dump($cpt_product_price);


    ob_start();
    if ( !empty($cpt_product_price['_price']) ) 
    ?>
    <form action="" method="post">
        <input name="add-to-cart" type="hidden" value="<?php echo $post->ID ?>" />
        <input name="quantity" type="number" value="1" min="1"  />
        <input name="submit" type="submit" value="Add to cart" />
    </form>
    <?php
    
    return $content . ob_get_clean();


*/




function rei_add_to_cart_button()
    global $post;
    if ($post->post_type !== 'products') return; 
    //var_dump($content);



    $get_ecommerce = get_field('e-commerce', get_the_ID());
    //var_dump($get_ecommerce);

    $get_ecommerce_price = $get_ecommerce['global']['price'];

    //global

    //price

    //$cpt_product_price = get_field('product_specifications', get_the_ID());


    //var_dump($cpt_product_price);
    //var_dump($cpt_product_price);

    ob_start();
    if ( !empty($get_ecommerce_price) ) 
    ?>
    <form action="" method="post">
        <input name="_gram" type="hidden" value="10">
        <input name="add-to-cart" type="hidden" value="<?php echo $post->ID ?>" />
        <input name="quantity" type="number" value="1" min="1"  />
        <input name="submit" type="submit" value="Add to cart" />
    </form>
    <?php
    
    return ob_get_clean();

但是现在我需要在产品页面上添加一些自定义字段,一个包含“黑色”和“白色”颜色的下拉列表,这只是一个普通的下拉列表。当我选择一个将显示在产品名称下的购物车上的值时,我该怎么做

【问题讨论】:

【参考方案1】:

更新 2

尝试以下操作(通常会在单个产品页面中添加下拉菜单并在购物车项目中保存/显示所选值)

// Frontend: custom select field (dropdown) in product single pages
add_action( 'woocommerce_before_add_to_cart_button', 'fabric_length_product_field' );
function fabric_length_product_field() 
    global $product;

    // Select field
    woocommerce_form_field('fitting_color', array(
        'type'     => 'select',
        'class'    => array('my-field-class form-row-wide'),
        'label'    => __('_fitting_color', 'woocommerce'),
        'required' => true, // or false
        'options'  => array(
            ''    => __('Select a color', 'woocommerce'),
            'black'    => __('Black', 'woocommerce'),
            'white'    => __('White', 'woocommerce'),
        ),
    ),'');


// Add "fitting_color" selected value as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_cart_item_data', 20, 2 );
function add_custom_cart_item_data( $cart_item_data, $product_id )
    if( isset($_POST['fitting_color']) && ! empty($_POST['fitting_color'])) 
        $cart_item_data['fcolor']= array(
            'value' => esc_attr($_POST['fitting_color']),
            'unique_key' => md5( microtime() . rand() ), // <= Make each cart item unique
        );
    
    return $cart_item_data;



// Display custom cart item data in cart and checkout pages
add_filter( 'woocommerce_get_item_data', 'display_custom_cart_item_data', 10, 2 );
function display_custom_cart_item_data( $cart_item_data, $cart_item ) 
    if ( isset( $cart_item['fcolor']['value'] ) )
        $cart_item_data[] = array(
            'name' => __( 'Fitting color', 'woocommerce' ),
            'value' => $cart_item['fcolor']['value'],
        );
    
    return $cart_item_data;

代码在您的活动子主题(或活动主题)的 function.php 文件中。它应该可以工作。


为了保存/显示订单(并显示在电子邮件通知中),您将使用:

// Save chosen slelect field value to each order item as custom meta data and display it everywhere
add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_product_fitting_color', 10, 4 );
function save_order_item_product_fitting_color( $item, $cart_item_key, $values, $order ) 
    if( isset($values['fcolor']['value']) ) 
        $key = __('Fitting color', 'woocommerce');
        $value = $values['fcolor']['value'];
        $item->update_meta_data( $key, $value );
    


以及缺少的字段验证:

// Field validation
add_filter( 'woocommerce_add_to_cart_validation',  'dropdown_fitting_color_validation', 10, 3 );
function dropdown_fitting_color_validation( $passed, $product_id, $quantity ) 
    if( isset($_POST['fitting_color']) && empty($_POST['fitting_color']) ) 
        wc_add_notice( __( "Please select a Fitting color", "woocommerce" ), 'error' );
        return false;
    

    return $passed;

【讨论】:

嗨 @loicTheAztec,它在常规 woo 产品上运行良好,但在自定义帖子类型页面上无法运行 我想我现在可以在 CPT 上使用它了,我刚刚删除了第一个操作 ( add_action( 'woocommerce_before_add_to_cart_button', 'fabric_length_product_field' ); ) 并将这个函数 (fabric_length_product_field()) 包含在 add to购物车形式

以上是关于在产品中添加自定义字段以显示在购物车、结帐和订单中的主要内容,如果未能解决你的问题,请参考以下文章

WooCommerce:将自定义 Metabox 添加到管理订单页面

如何在 shopify 产品页面上添加自定义文本框字段

在 Woocommerce 中的购物车和结帐总计上插入自定义总计行

在购物车和结帐的 WooCommerce 产品名称中附加自定义字段值

从结帐页面 woocommerce 更新购物车中的产品

WooCommerce:在任何地方添加/显示产品或变体自定义字段