简体   繁体   中英

Add item to cart through a Get request with custom meta data in Woocommerce

I have created a button per item in the order view in woocommerce (inside the order-details-item.php) to enable the customer to add that item to the cart and so buy more. By using a href that builds on ?add-to-cart, I can get it to work fine, both for simple and variable products, and with different attributes.

The problem is that I have been unable to also pass on a custom meta field that I created (door width). I have tried several solutions, but to no avail so far.

Below my current code:

$url = $order->get_view_order_url() . '/?add-to-cart=' . $item['product_id'];
$simple_ = $product->is_type('simple');

if ( $simple_ != 'simple') {
  $url .= '&variation_id=' . $item['variation_id'];
  $attributes = wc_get_product_variation_attributes($item['variation_id']);
  foreach( $attributes as $key => $value ){ $url .= '&' . $key . '=' . $value; }

  $meta = wc_get_order_item_meta( $item_id ); 
  if ( $meta['Door width'][0] ) { $url .= '&attribute_Door width=' . $meta['Door width'][0]; }
}

<a href="<?php echo $url; ?>"><?php echo __('Order again', 'woocommerce'); ?></a>

I have looked for solutions and suggestions on other posts, but could not find the answer.

I wonder if someone has a suggestion.

Adding &attribute_Door width=value to the url can't work, as you can't use blank spaces. Instead you will use any slug that will be saved and renamed in cart later…

Also you are using outdated code as since Woocommerce version 3, order item are now new class objects and properties can't be accessed directly.

So I have revisited your code deeply:

$url = $order->get_view_order_url() . '/?add-to-cart=' . $item->get_product_id();

$variation_id = $item->get_variation_id();

if ( $variation_id > 0 ) {
    $url .= '&variation_id=' . $variation_id;
    foreach( wc_get_product_variation_attributes( $variation_id ) as $key => $value ) 
        $url .= '&' . $key . '=' . $value;
    
    $meta = wc_get_order_item_meta( $item_id ); 
    if ( ! empty( $meta['Door width'][0] ) )
        $url .= '&door_width=' . esc_attr( $meta['Door width'][0] );
}

// Display the button
$button_text = __('Order again', 'woocommerce');
echo '<a href="' . $url . '">' . $button_text . '</a>';

So for a product variation I get something like this (custom testing) :
?add-to-cart=40&variation_id=41&attribute_pa_color=black&attribute_pa_volume-special=15&attribute_pa_quantity=dozen&door_width=100

Now you will need to get door_width when added to cart to save it in cart object and display it as an attribute in cart and checkout:

// Store custom data in cart item
add_action( 'woocommerce_add_cart_item_data','save_custom_data_in_cart', 20, 2 );
function save_custom_data_in_cart( $cart_item_data, $product_id ) {
    if( isset( $_REQUEST['door_width'] ) )
        $cart_item_data['door_width'] = array(
            'label' => __('Door with'),
            'value' => esc_attr( $_REQUEST['door_width'] ),
        );

    if( count($cart_item_data['door_width']) > 0 )
        $cart_item_data['door_width']['key'] = md5( microtime().rand() );

    return $cart_item_data;
}

// Display item custom data in cart and checkout pages
add_filter( 'woocommerce_get_item_data', 'render_custom_data_on_cart_and_checkout', 20, 2 );
function render_custom_data_on_cart_and_checkout( $cart_data, $cart_item ){
    $custom_items = array();

    if( !empty( $cart_data ) )
        $custom_items = $cart_data;

    if( isset( $cart_item['door_width'] ) )
        $custom_items[] = array(
            'name'  => $cart_item['door_width']['label'],
            'value' => $cart_item['door_width']['value'],
        );

    return $custom_items;
}

Code goes in function.php file of your active child theme (or active theme).

Tested and works. It should works also for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM