1

I am implementing the custom Buy Now button in my plugin. I had placed the Buy Now button on the product page using this hook

  add_action( 'woocommerce_after_add_to_cart_button', 'myCustomBuyNowButton');

So, my next step is to add the product to the cart with quantity, variation details, which I am able to achieve by writing the following function i.e

(function ($) {

$(document).on('click', '.single_add_to_cart_button', function (e) {
    e.preventDefault();

    var $thisbutton = $(this),
    $form = $thisbutton.closest('form.cart'),
    id = $thisbutton.val(),
    product_qty = $form.find('input[name=quantity]').val() || 1,
    product_id = $form.find('input[name=product_id]').val() || id,
    variation_id = $form.find('input[name=variation_id]').val() || 0;

    var data = {
        action: 'woocommerce_ajax_add_to_cart',
        product_id: product_id,
        product_sku: '',
        quantity: product_qty,
        variation_id: variation_id,
    };

    $(document.body).trigger('adding_to_cart', [$thisbutton, data]);

    $.ajax({
        type: 'post',
        url: wc_add_to_cart_params.ajax_url,
        data: data,
        beforeSend: function (response) {
            $thisbutton.removeClass('added').addClass('loading');
        },
        complete: function (response) {
            $thisbutton.addClass('added').removeClass('loading');
        },
        success: function (response) {

            if (response.error && response.product_url) {
                window.location = response.product_url;
                return;
            } else {
                $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $thisbutton]);
            }
        },
    });

    return false;
});
})(jQuery);

& ajax is calling the following hook

add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');

function woocommerce_ajax_add_to_cart() {

$product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_POST['product_id']));
$quantity = empty($_POST['quantity']) ? 1 : wc_stock_amount($_POST['quantity']);
$variation_id = absint($_POST['variation_id']);
$passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);
$product_status = get_post_status($product_id);

if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id) && 'publish' === $product_status) {

    do_action('woocommerce_ajax_added_to_cart', $product_id);

    if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
        wc_add_to_cart_message(array($product_id => $quantity), true);
    }

    WC_AJAX :: get_refreshed_fragments();
} else {

    $data = array(
        'error' => true,
        'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id));

    echo wp_send_json($data);
}


wp_die();
}

But I am stuck in adding the custom plugin data to the cart along with the quantity and variation details.

For ex: If the admin has installed a custom product fields plugin that helps them to add the custom fields on their product page to collect extra information. I need to add that information also to the cart.

Can anyone please help me to resolve this issue? Thanks in advance.

ManuGN
  • 21
  • 4
  • If the plugin for custom fields is ACF or Metabox sure you can loop for fields and if there is any to grab info BUT you may not want all fields right ? Easy routh is knowing fields names beforehand. You want this information to be collected in order too or not ? Are those fields related to checkout process or not ? There are alot of stuff to cover to just pull some data. – Snuffy Nov 29 '21 at 08:15
  • Yes, these fields are related to the checkout process and also need it in order. By knowing the field's name means we need to get those names from the front end page only right as we don't know which plugin merchant has been installed and what will the field's name is. @MartinMirchev – ManuGN Nov 29 '21 at 08:28
  • Ok check my next post https://stackoverflow.com/questions/70151176/how-to-add-custom-plugin-data-to-the-cart-in-woocommerce-using-custom-button-on/70154811#70154811 – gaurav sharma Nov 29 '21 at 12:40

2 Answers2

1

Use these hooks

// Add item data to the cart or define custom variable
add_filter( 'woocommerce_add_cart_item_data', 'add_cart_item_datax',10, 3 );

// Display item data to the cart or show custom variable
add_filter( 'woocommerce_get_item_data', 'get_cart_item_data', 10, 2 );


function add_cart_item_datax( $cart_item_data, $productId, $variationId ) {

    if ( empty( $cart_item_data['basicpluginstr'] ) ) {
            $cart_item_data['basicpluginstr'] = array();
    }

    $data[] = array(
            'name'  => 'Name',
            'value' => 'valus',
            'price' => 50
            );
            
    $cart_item_data['basicpluginstr'] = array_merge( $cart_item_data['basicpluginstr'], $data);

    return $cart_item_data;
}


function get_cart_item_data( $data, $cartItem ) {

    if ( isset( $cartItem['basicpluginstr'] ) ) {

        foreach ( $cartItem['basicpluginstr'] as $basicpluginstr ) {

            $name = 'PPPPPPP'; //$basicpluginstr['name'];  

            $value = '12364'; //$basicpluginstr['value'];  

            $price = '150'; //$basicpluginstr['price']; 

        }

        $data[] = array(
            'name' => $name,
            'value' => $value,
            'display' => 0
        );
    }

    return $data;
}


//Add meta to order - WC 2.x or save the data when the order is made
add_action( 'woocommerce_add_order_item_meta',  'add_order_item_meta' , 10, 2 );
function add_order_item_meta( $item_id, $values ) {
   
      if ( ! empty( $values['basicpluginstr'] ) ) {
          foreach ( $values['basicpluginstr'] as $basicpluginstr ) {

              $name = $basicpluginstr['name'];
              $value = $basicpluginstr['value'];
              woocommerce_add_order_item_meta( $item_id, $name, $value );

              //woocommerce_add_order_item_meta( $item_id, 'basicpluginstr', 'basicpluginstr value' );
          }
      }

}
gaurav sharma
  • 534
  • 2
  • 6
  • I had already tried this hook in my plugin, but when I log the `$cart_item_data` value it's coming as an empty array. I added this hook in my `woocommerce_ajax_add_to_cart` function before `add_to_cart` call. Am I doing anything wrong here? @gaurav sharma – ManuGN Nov 29 '21 at 08:53
  • This is working on cart page with woocommerce session ....After addtocart you have a go on cart page then log again. – gaurav sharma Nov 29 '21 at 09:04
  • Got it, but in my case, I am trying to get those details in the plugin code itself. And the custom field value will be coming from the frontend. Is there any way to get those data through this hook? @gaurav sharma – ManuGN Nov 29 '21 at 10:06
  • Ok check my next post – gaurav sharma Nov 29 '21 at 12:52
0

I have added a custom Field in admin and try to add itemdata in cart

    <?php
    /*
    * Plugin Name: Custom Woo option
    * Author: Gaurav Dev
    * Text Domain: custom-woo-option
    * Description: This is the Custom Woo option plugin
    * Version: 1.0.0
    */

    if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
     
    define( 'basicpluginstr_VERSION', '1.0.0' );
    define( 'basicpluginstr_URI', plugin_dir_url( __FILE__ ) );
    class basicpluginstr
    {
        //https://stackoverflow.com/questions/21650019/woocommerce-add-input-field-to-every-item-in-cart
        
        function __construct()
        {

            // Product data tabs
            add_filter( 'woocommerce_product_data_tabs', array( $this,'basicpluginstr_product_data_tabs') );

            // Product data panels
            add_action( 'woocommerce_product_data_panels', array( $this,'basicpluginstr_product_data_panels') );
            
            // Add to cart
            add_filter('woocommerce_add_cart_item', array($this, 'add_cart_item'), 999999999999999999, 1); 

            // Add item data to the cart or define custom variable
            add_filter( 'woocommerce_add_cart_item_data', array($this,'add_cart_item_data'),10, 3 );
            
            // Display item data to the cart or show custom variable
            add_filter( 'woocommerce_get_item_data', array($this,'get_cart_item_data'), 10, 2 );

            // Load cart data per page load
            add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_from_session' ), 999999999999999999, 2 );

            //Add meta to order - WC 2.x or save the data when the order is made
            add_action( 'woocommerce_add_order_item_meta',  array($this,'add_order_item_meta') , 10, 2 );

            //Save post
            add_action( 'save_post', array($this,'custom_wp_bakery_save_post_fun'), 12, 1);

            //Add Field on single Product Page
            add_action( 'woocommerce_before_add_to_cart_button', array($this,'add_name_on_tshirt_field'));
            
        }


        /*
        * Defined Product Data Tab 
        */
        function basicpluginstr_product_data_tabs( $tabs ) {
            $tabs['basicpluginstr'] = array(
                'label'  => esc_html__( 'basicpluginstr', 'cus-price-cal' ),
                'target' => 'basicpluginstr_settings',
                'class'  => array( 'show_if_basicpluginstr' ),
            );
            return $tabs;
        }

        /*
        * Define Product Data Panel
        */
        function basicpluginstr_product_data_panels() {
            global $post;
            $post_id = $post->ID;
            $_core_price = get_post_meta( $post_id, '_core_price', true );
            ?>
            <div id='basicpluginstr_settings' class='panel woocommerce_options_panel basicpluginstr_options_panel'>
                <h1>Core Price</h1>
                <input type="Text" name="_core_price" id="_core_price" value="<?php echo $_core_price;?>">
            </div>
            <?php
        }


        function add_cart_item($cart_item) { 

            if ( isset( $cart_item['basicpluginstr'] ) ) {

                foreach ( $cart_item['basicpluginstr'] as $basicpluginstr ) {
      
                    $_core_price = $basicpluginstr['_core_price']; 
                }

                $cart_item['data']->set_price($_core_price);
                //$cart_item['data']->adjust_price( $extra_cost );
            }

            return $cart_item;
        }

          function add_cart_item_data( $cart_item_data, $productId, $variationId ) {

            if ( empty( $cart_item_data['basicpluginstr'] ) ) {
                    $cart_item_data['basicpluginstr'] = array();
            }

            $data[] = array(
                    'name'  => 'Core Price',
                    'value' => '10',
                    '_core_price' => 10
                    );
                    
            $cart_item_data['basicpluginstr'] = array_merge( $cart_item_data['basicpluginstr'], $data);


           
            return $cart_item_data;
        }


          function get_cart_item_data( $data, $cartItem ) {

            if ( isset( $cartItem['basicpluginstr'] ) ) {

                foreach ( $cartItem['basicpluginstr'] as $basicpluginstr ) {

                    $name = $basicpluginstr['name'];  

                    $value = $basicpluginstr['value'];   

                }

                $data[] = array(
                    'name' => $name,
                    'value' => $value,
                    'display' => 0
                );
            }

            return $data;
        }


        function get_cart_item_from_session($cart_item, $values) {

            if ( ! empty( $values['basicpluginstr'] ) ) {
                $cart_item['basicpluginstr'] = $values['basicpluginstr'];
                $cart_item = $this->add_cart_item( $cart_item );
            }
            return $cart_item;

        }

        function add_order_item_meta( $item_id, $values ) {
         
            if ( ! empty( $values['basicpluginstr'] ) ) {
                foreach ( $values['basicpluginstr'] as $basicpluginstr ) {

                    $name = $basicpluginstr['name'];
                    $value = $basicpluginstr['value'];
                    woocommerce_add_order_item_meta( $item_id, $name, $value );
                    //woocommerce_add_order_item_meta( $item_id, 'basicpluginstr', 'basicpluginstr value' );
                }
            }

        }


        function custom_wp_bakery_save_post_fun($post_id){
            if (isset($_POST['_core_price'])) {
              update_post_meta($post_id, '_core_price', $_POST['_core_price']);
            }
        }

        function add_name_on_tshirt_field() {

            $_core_price = get_post_meta( get_the_ID(), '_core_price', true );

            if (!empty($_core_price)) {
                 echo '<table class="variations" cellspacing="0">
                      <tbody>
                          <tr>
                          <td class="label"><label for="color">Core Price</label></td>
                          <td class="value">
                              <input type="text" name="_core_price" value="'.$_core_price.'" />
                          </td>
                      </tr>                             
                      </tbody>
                  </table>';
            }

         
        }

    }
    new basicpluginstr();

    }

Please try the example in your working environment and modify it accordingly

enter image description here

enter image description here

enter image description here

enter image description here

gaurav sharma
  • 534
  • 2
  • 6
  • thank you so much for explaining the entire flow here. But here you are defining the custom fields, but in our code, we wanted to get the other custom plugin fields information also, in which we don't know the filed names. But let me go through the function which you mentioned here. – ManuGN Nov 29 '21 at 17:09
  • You have print_r the cart array and try to find the "other custom plugin fields information" node then replace my custom field with your custom plugin info. – gaurav sharma Nov 30 '21 at 07:01