Here’s an outline of the WooCommerce life cycle and where you can use hooks and filters to allow custom items to be put on the product page and pass through to the Basket, the Cart and the Order.
I’ve used this on a Variable product that requires additional information to fulfil the order.
When clicking on a Product the following Hooks and filters will come into play in this order.
For convenience I’ve included example code (get your debugger out to see what’s really going on):-
class ManageCart { function __construct() { /* ** Display custom fields. First call after clicking on a product to select options. */ add_action('woocommerce_before_add_to_cart_button', array($this, 'display_customisation_fields')); /* ** Watch variation changing. After the Product is displayed you can use this hook to put a watch on any variation changes. */ add_action('woocommerce_before_add_to_cart_quantity', array($this, 'watch_variation_change')); /* ** Validate inputs. Called when the user clicks the Add To Basket button */ add_filter('woocommerce_add_to_cart_validation', array($this, 'validate_customisation_fields'), 10, 3); /* ** Add to cart. Move your custom inputs into the cart. */ add_filter('woocommerce_add_cart_item_data', array($this, 'add_custom_fields_item_data'), 10, 4); /* ** Show data in cart. Fetch your values for the cart. */ add_filter('woocommerce_get_item_data', array($this, 'displaycustomisations_in_cart'), 10, 2); /* ** Add to Order when user clicks Confirm Order */ add_action('woocommerce_checkout_create_order_line_item', array($this, 'checkout_create_order_line_item'), 20, 4); } function display_customisation_fields() { // Render your HTML controls from here. // I used Product attributes to help define which fields are required. // Can be fetched but doing.... global $post; $this->product = wc_get_product($post->ID); $product = wc_get_product($product_id); $all_attributes = $product->get_attributes(); //... echo '<input type="text" name="custom-number"> } /** * Watch the variation change and fill the Width input with the variation value. */ function watch_variation_change() { global $product; if ($product->is_type('variable')) { ?> <script> jQuery(document).ready(function($) { /** * The hidden field with class variation_id has the value of the currently selected variation id (setup by Woo). */ $('input.variation_id').change(function() { // Do JS/jQuery code in here to respond to a re-selection of the variation } </script> <?php } } /* ** Validate inputs */ function validate_customisation_fields($passed, $product_id, $quantity) { // This is where you can access the POST variable returned from the form. // If you need the variation it's in a hidden field.... $variation_id = filter_input(INPUT_POST, 'variation_id', FILTER_SANITIZE_NUMBER_INT); $a_custom_number_inputted = filter_input(INPUT_POST, 'custom-number', FILTER_SANITIZE_NUMBER_INT); // Do your own validation in here. If all OKAY return TRUE; // If there is a problem.... // Set an error message that will be automatically displayed for you. wc_add_notice(__('Please enter a valid number', 'theme'), 'error'); return FALSE; } /* ** Add to cart */ function add_custom_fields_item_data($cart_item_data, $product_id, $variation_id, $quantity) { // Add your custom value to the cart item array $cart_item_data['my_custom_value'] = $post_data; // You'd probably want to get this from a class property that is set in the validation method. // etc for all custom fields .... return $cart_item_data; } /** * Show the customisations in the cart. */ function displaycustomisations_in_cart($item_data, $cart_item) { // At this point I re-fetch the product attributes for this product as a reminder of what to expect. Your gig might vary. // This will display an item in the cart with the label 'A Magic Number' $item_data[] = array( 'key' => 'A Magic Number', 'value' => wc_clean($cart_item['my_custom_value']), 'display' => '', ); return $item_data; } /* ** Add custom meta to Order */ function checkout_create_order_line_item($item, $cart_item_key, $values, $order) { $item->add_meta_data('Label on Order', $values['my_custom_value']); } }
Leave a Reply
You must be logged in to post a comment.