Check out my visual testing tool https://diffy.website. It helps to save testing time during deployments and development.
One of new drupal 7 projects I had the task to add new step in checkout process. In this article I would like to share how easy it is now with Drupal Commerce
First of all lets look to the new API of the commerce checkout. All the pages are defined with hook_commerce_checkout_page_info() (you can see example implementation in commerce_checkout_commerce_checkout_page_info()). Every page consists of the panes that are defined in hook_commerce_checkout_pane_info() (as example please take a look at commerce_checkout_commerce_checkout_pane_info()). So it is very straightforward and clear. We need to add new page and new pane.
So lets add our new custom step. In my task it was to create separate node as one of the steps of checkout.
In order to accomplish this we need to implement hook_commerce_checkout_page_info()
/** * Implements hook_commerce_checkout_page_info(). */ function example_commerce_checkout_page_info() { $checkout_pages = array(); $checkout_pages['example_form_page'] = array( 'name' => t('Example form'), 'title' => t('Fill the form to proceed with checkout'), 'weight' => -10, 'status_cart' => FALSE, 'buttons' => TRUE, ); return $checkout_pages; }
Then we need to create pane for this page.
/** * Implements hook_commerce_checkout_pane_info(). */ function example_commerce_checkout_pane_info() { $checkout_panes = array(); $checkout_panes['example_pane'] = array( 'title' => t('Node form'), 'file' => 'example.checkout_pane.inc', 'base' => 'example_pane', 'page' => 'example_form_page', 'callbacks' => array( 'checkout_form_submit' => 'example_pane_checkout_form_submit', ), 'fieldset' => FALSE, ); return $checkout_panes; }
Then we should create separate file example.checkout_pane.inc where we store form for our pane.
/** * Custom checkout pane. * * Function name should consist of <pane key>_checkout_form. */ function example_pane_checkout_form($form, &$form_state, $checkout_pane, $order) { global $user; $pane_form = array(); // Retrieve article node form. $type = 'page'; $node = array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'language' => LANGUAGE_NONE); // Merge empty node with order node data. if (isset($order->data['node'])) { $node = array_merge($node, $order->data['node']); } $node = (object) $node; module_load_include('inc', 'node', 'node.pages'); // Retrieve node form. $node_form_state = array(); $node_form_state['build_info']['args'] = array($node); $node_form_state += form_state_defaults(); $pane_form = drupal_retrieve_form($type . '_node_form', $node_form_state); // Hide some node form elements. $pane_form['actions']['submit']['#access'] = FALSE; $pane_form['actions']['preview']['#access'] = FALSE; $pane_form['author']['#access'] = FALSE; $pane_form['options']['#access'] = FALSE; $pane_form['revision_information']['#access'] = FALSE; return $pane_form; } /** * Custom checkout pane submit handler. * * Save node data to order. */ function example_pane_checkout_form_submit($form, &$form_state, $checkout_pane, &$order) { $order->data['node'] = $form_state['values']; }
After retrieve node form (we user "page" content type) we remove some form elements.
In submit handler we save filled data to $order->data property so it goes along with our order to next steps. As a tip at the moment we cannot use dpm() function in submit handler as these messages are not shown, so we can use simple output with print_r() to debug submit handler.
In my case I needed to save the node only after all checkout procedure is finished. For this we can use hook hook_commerce_checkout_router() in following way:
/** * Implements hook_commerce_checkout_router(). * * Create node on complete checkout page. */ function example_commerce_checkout_router($order, $checkout_page) { if ($checkout_page['page_id'] != 'complete' || !isset($order->data['node'])) { return; } $node = (object) $order->data['node']; node_save($node); unset($order->data['node']); }
So this is it. Now we have custom built step in checkout that works very nicely using several hooks and building custom checkout pane.
I hope you have enjoyed and can see how flexible Drupal commerce is.
You are welcome to download source code of the example module below.
Comments
thanks
Great tutorial, and glad to
Thanks for the feedback!
Using Webforms with this setup
Figured out my last problem but...
I believe you should take a
sam
Error when trying to use a custom content type
As I remember, FieldAPI keeps
Workaround we used