If you’re running a WooCommerce payment gateway for your project but you find that you need to add some additional fields to the checkout to keep your client happy, or indeed to placate some law in whichever random country takes their fancy to change the rules of engagement. Of course you could add one of the plethora of plugins out there to do the job, but of course you know and understand the risks of your client having access to that sort of thing whilst you’re not looking.
To begin with there are two things you absolutely need to understand, adding woocommerce checkout fields into the actual checkout form can be any type apart from ‘file’, if you want to upload anything, then you need to create hooks that exist outside of the checkout_form and add meta data to the order on the fly. You will waste hours of your life trying to find the answer, so save yourself the bother.
With the above in mind, you will also need to consider how to monitor what is going on, the obvious answer is to use $_SESSION data, then if you have something great, otherwise you have to get something .. simple really.
The Woocommerce checkout page is basically just AJAX calls for verification, updates, etc. So any solution developed for uploading makes sense to also be based around an AJAX call.
You also need to consider what it is you are uploading, especially given its during the checkout process, generally this is a very private affair. For example if it is a medical question site, you certainly don’t want the images just sitting in the media library for all and sundry to have a look at after the fact.
As you can see, there is some consideration you need to apply to uploading files to the checkout, content and context are key, your visitors privacy is of utmost paramount.
So now we can see quite clearly where things go in terms of the processes that need to happen, infinitely more valuable than endless examples of stuff without context. What is it they say? A picture is worth a thousand words?
[php] <?php // Not real, just an example function photo_section( $checkout ) { photoid_start_session();?> <form enctype="multipart/form-data" id="photoform" name="photoform" method="POST"> <div id="photo"> <h3><?php _e('Photo', 'photoupload'); ></h3> <?php $img = $photosession-&gt;imgUrl(); if ($img) $src = "src='$img'"; else $src = ''; ?> <img id="photoholder" name="photoholder" class="photo-holder" <?php _e($src); /> <label for="photoupload" class="btn primary">Choose file</label> <input type="hidden" id="pn" name="pn" value="<?php echo wp_create_nonce('photoup'); ?>" /> <input type="file" name="photofile" id="photofile" style="display: none;" /> <input type="submit" value="upload" /> </div> </form> <?php } add_action( 'woocommerce_before_checkout_form', 'photo_section', 10, 1 ); ?> [/php]
A quick breakdown of what’s there, it’s pretty simple really. A form … a standard multipart form for any other type of file upload in PHP. The only addition to the form is the use of WordPress nonce’s, with all things wordpress it is standard practise to implement and use the nonce system for anything requiring users to submit data or files to the website. In this instance we use the label to select our file rather than the file input, because, well quite franky the file inputs are bloody ugly.
When you load your checkout page now, you will see this shiny new form sitting proudly at the top of the page.
The final issue here is making our new image a requirement of the checkout process, as it’s not a part of the checkout_form, we need to add some additional code into the checkout_process that checks our own unique session identifiers.
[php] <?php function photo_checkout_process() { photo_start_session(); $photo = $photosession->getPhotoId(); if ( ! $photo || empty($photo) ) wc_add_notice( __( '<strong>Must attach a photo ID</strong> to complete your order.' ), 'error' ); } add_action('woocommerce_checkout_process', 'photo_checkout_process'); ?> [/php]
So we have a look to see if the visitor has added an image (handled by the AJAX side of things) and if not we display a notice and create an error. Simple really when you think about it and it all hooks into the action woocommerce_checkout_process.
The last thing we need to do with the hooks is to save the newly uploaded image information to the actual order, we can of course add the meta data to the order view in the admin area, but I am sure you can work out how to do that on your own? Maybe I will cover it in a separate article just in case.
[php] <?php // Save away, save away .. save away function photo_save_field( $order_id ) { photo_start_session(); $photo = $photosession->getPhotoId(); if ($photo) update_post_meta($order_id, '_photo', $photo); } add_action('woocommerce_checkout_update_order_meta', 'photo_save_field'); ?> [/php]
And that’s that all saved against the order generated.
I haven’t included the AJAX code for this, again, maybe another article at some point, but you get the idea, you can see what needs to be done and where and I have tried to point out where the pitfalls are for you when you consider uploading to the checkout.
I also notice that I didn’t include a normal extra field example, I shall do that in a separate article at some point, something succinct. But here is a clue in the mean time woocommerce_before_order_notes.
Leave a Reply