2

I think step 3 is not working. In the Orders section in the backend admin I do not see the product name concatenated to the Free Sample text. It works in the Cart Page, it shows Free Sample ( Product Name ) and in Checkout, but it does not work in orders. In Orders I only see "Free Sample" Can anyone help?

/**
 * @snippet       Add Free Sample to Cart @ Single Product
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @testedwith    WooCommerce 3.9
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */

// -------------------------
// 1. Display Free Sample Add to Cart 
// Note: change "12345" with Free Sample ID

add_action( 'woocommerce_single_product_summary', 'bbloomer_add_free_sample_add_cart', 35 );

function bbloomer_add_free_sample_add_cart() {
   ?>
      <form class="cart" method="post" enctype='multipart/form-data'>
      <button type="submit" name="add-to-cart" value="111" class="single_add_to_cart_button button alt">Order a Free Sample</button>
      <input type="hidden" name="free_sample" value="<?php the_ID(); ?>">
      </form>
   <?php
}

// -------------------------
// 2. Add the custom field to $cart_item

add_filter( 'woocommerce_add_cart_item_data', 'bbloomer_store_free_sample_id', 9999, 2 );

function bbloomer_store_free_sample_id( $cart_item, $product_id ) {
   if ( isset( $_POST['free_sample'] ) ) {
         $cart_item['free_sample'] = $_POST['free_sample'];
   }
   return $cart_item; 
}

// -------------------------
// 3. Concatenate "Free Sample" with product name (CART & CHECKOUT)
// Note: rename "Free Sample" to your free sample product name

add_filter( 'woocommerce_cart_item_name', 'bbloomer_alter_cart_item_name', 9999, 3 );

function bbloomer_alter_cart_item_name( $product_name, $cart_item, $cart_item_key ) {
   if ( $product_name == "Free Sample" ) {
      $product = wc_get_product( $cart_item["free_sample"] );
      $product_name .=  " (" . $product->get_name() . ")";
   }
   return $product_name;
}

// -------------------------
// 4. Add "Free Sample" product name to order meta
// Note: this will show on thank you page, emails and orders

add_action( 'woocommerce_add_order_item_meta', 'bbloomer_save_posted_field_into_order', 9999, 2 );

function bbloomer_save_posted_field_into_order( $itemID, $values ) {
    if ( ! empty( $values['free_sample'] ) ) {
      $product = wc_get_product( $values['free_sample'] );
      $product_name = $product->get_name();
      wc_add_order_item_meta( $itemID, 'Free sample for', $product_name );
    }
}
Paul
  • 53
  • 4
  • Take a look at this, this is about exactly the same (only the condition of the tag is not in your question) https://stackoverflow.com/a/60252556/11987538 – 7uc1f3r Feb 17 '20 at 21:29
  • @L7c1f3r I was trying to incorporate that into my code but was unable to. I am not sure what to do really this is beyond me at this time. – Paul Feb 17 '20 at 21:45

1 Answers1

1

Here is a simple example

function my_add_cart_item_data( $cart_item, $product_id ) {
    $cart_item['my_text'] = 'MY CUSTOM TEXT';
    return $cart_item; 
}
add_filter( 'woocommerce_add_cart_item_data', 'my_add_cart_item_data', 10, 2 );

function custom_cart_items_prices( $cart ) {

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item ) {

        // Get an instance of the WC_Product object
        $product = $cart_item['data'];

        // Get the product name
        $original_name = $product->get_name();

        // Extra text
        $extra_text = $cart_item['my_text'];

        // Set the new name 
        if( method_exists( $product, 'set_name' ) ) {
            $product->set_name( $original_name . ' + ' . $extra_text );
        }
    }
}
add_action( 'woocommerce_before_calculate_totals', 'custom_cart_items_prices', 10, 1 );

With your code example this becomes something like

// 1.
add_action( 'woocommerce_single_product_summary', 'bbloomer_add_free_sample_add_cart', 35 );
function bbloomer_add_free_sample_add_cart() {
    ?>
        <form class="cart" method="post" enctype='multipart/form-data'>
        <button type="submit" name="add-to-cart" value="111" class="single_add_to_cart_button button alt">Order a Free Sample</button>
        <input type="hidden" name="free_sample" value="<?php the_ID(); ?>">
        </form>
    <?php
}

// 2.
add_filter( 'woocommerce_add_cart_item_data', 'bbloomer_store_free_sample_id', 9999, 2 );
function bbloomer_store_free_sample_id( $cart_item, $product_id ) {
    if ( isset( $_POST['free_sample'] ) ) {
        $cart_item['free_sample'] = $_POST['free_sample'];
    }
    return $cart_item; 
}

// 3
add_action( 'woocommerce_before_calculate_totals', 'custom_cart_items_prices', 10, 1 );
function custom_cart_items_prices( $cart ) {

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item ) {

        // Get an instance of the WC_Product object
        $product = $cart_item['data'];

        // Get the product name
        $original_name = $product->get_name();

        // Extra text
        $extra_text = $cart_item['free_sample'];

        // Set the new name 
        if( method_exists( $product, 'set_name' ) ) {
            $product->set_name( $original_name . ' + ' . $extra_text );
        }
    }
}
7uc1f3r
  • 28,449
  • 17
  • 32
  • 50
  • Thank you. This returns Free Sample + "ID". Can we make it so that it returns the product name instead of the ID? – Paul Feb 17 '20 at 22:04
  • I have not tested the code of bbloomer, try my first code example (Here is a simple example), if this works then the problem lies with the code of bbloomer. Can you confirm this? – 7uc1f3r Feb 17 '20 at 22:13
  • 1
    I have fixed this by changing the value="" to the title. Yes I can confirm this is a problem that lies within the code. – Paul Feb 17 '20 at 22:16