commerce_reorder.module in Commerce Reorder 7.2
Same filename and directory in other branches
Allows users to create a new order from their order history.
File
commerce_reorder.moduleView source
<?php
/**
* @file
* Allows users to create a new order from their order history.
*/
/**
* Implementation of hook_menu
*/
function commerce_reorder_menu() {
$items = array();
// Reorder tab on orders.
$items['admin/commerce/orders/%commerce_order/reorder'] = array(
'title' => 'Reorder',
'page callback' => 'commerce_reorder_reorder_callback',
'page arguments' => array(
3,
),
'access arguments' => array(
'commerce_reorder_access',
),
'type' => MENU_LOCAL_ACTION,
'weight' => 15,
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
);
return $items;
}
/**
* Implementation of hook_permission().
*/
function commerce_reorder_permission() {
return array(
'commerce_reorder_access' => array(
'title' => t('Reorder a previous order'),
'description' => t('Add contents of an order to a new cart.'),
),
);
}
/**
* Implements hook_views_api().
*/
function commerce_reorder_views_api() {
return array(
'api' => '3',
'path' => drupal_get_path('module', 'commerce_reorder') . '/includes/views',
);
}
/**
* Dynamically add a CSRF-protection token to the reorder-links usin a
* preprocess function.
*
* @see http://drupal.org/node/755584 for a reference to CSRF tokens for menus.
*/
function commerce_reorder_preprocess_link(&$variables) {
if (strpos($variables['path'], 'admin/commerce/orders/') === 0 && substr($variables['path'], -8) == '/reorder') {
$path = explode('/', $variables['path']);
$variables['options']['query']['token'] = drupal_get_token('commerce_reorder:' . $path[3]);
}
}
/**
* Perform the reorder action for the operations menu
*/
function commerce_reorder_reorder_callback($order) {
if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'commerce_reorder:' . $order->order_id) || !commerce_order_access('view', $order)) {
return MENU_ACCESS_DENIED;
}
$profile_types = commerce_customer_profile_types();
foreach ($profile_types as $type) {
$default_profile_options[$type] = TRUE;
}
// Ensure that the copied order belongs to the original owner.
commerce_reorder_helper($order, null, array(
'copy_profiles' => $default_profile_options,
'suppress_cart_messages' => TRUE,
));
$new_order = commerce_cart_order_load($order->uid);
// Redirect to the new order.
drupal_set_message(t('Order copied.'));
drupal_goto('admin/commerce/orders/' . $new_order->order_id);
}
/**
* Helper function to reorder a previous order.
*
* This function copies the line items and optionally, profile fields, over to a
* the shopping cart of the targeted uid.
*
* @param object $order
* The commerce_order object to reorder.
* @param int $uid
* An account uid. The uid will be used with the add to cart functions for
* adding products to a cart.
* @param array $settings
* An optional array that may contain the following values:
* - copy_profiles: An array of profile types from
* commerce_customer_profile_types() to be copied to the order. It will look
* for the fields 'commerce_customer_TYPE' on the order. e.g.
* array('shipping' => 'shipping').
*/
function commerce_reorder_helper($order = NULL, $uid = NULL, $settings = array()) {
$profile_types = array_keys(commerce_customer_profile_types());
foreach ($profile_types as $type) {
$default_profile_options[$type] = FALSE;
}
// Set the default copy options.
$settings = (array) $settings + array(
'copy_profiles' => $default_profile_options,
'copy_profiles_source' => 'order',
'suppress_cart_messages' => FALSE,
);
if (!isset($order)) {
return;
}
if (empty($uid)) {
$uid = $order->uid;
}
if ($settings['suppress_cart_messages']) {
$existing_status_updates = $_SESSION['messages']['status'];
}
// Get the line items of the order.
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
foreach ($order_wrapper->commerce_line_items as $line_item_wrapper) {
if (in_array($line_item_wrapper->type
->value(), commerce_product_line_item_types())) {
$product = $line_item_wrapper->commerce_product
->value();
if ($product->status) {
$line_item = $line_item_wrapper
->value();
// Generate a line item product based in the current one.
$new_line_item = commerce_product_line_item_new($product, $line_item->quantity, $line_item->order_id, $line_item->data, $line_item->type);
// Merge both line items to get the fields (if any).
$new_line_item = (object) array_merge((array) $line_item, (array) $new_line_item);
// @TODO Add option to combine / add separately.
// See @commerce_cart_product_add
commerce_cart_product_add($uid, $new_line_item);
}
else {
drupal_set_message(t('Some products weren\'t copied to the cart as they aren\'t currently available.'), 'status', FALSE);
}
}
else {
drupal_set_message(t('Some products weren\'t copied to the cart as they aren\'t currently available.'), 'status', FALSE);
}
}
// Copy over profiles if they are set.
$cart = $cart_wrapper = null;
foreach ($settings['copy_profiles'] as $profile_type => $copy) {
if ($profile_type !== $copy) {
continue;
}
if (!isset($cart)) {
$cart = commerce_cart_order_load($uid);
$cart_wrapper = entity_metadata_wrapper('commerce_order', $cart);
}
$field_name = 'commerce_customer_' . $profile_type;
$profile_id = FALSE;
// If the new order doesn't have this field defined, skip it.
if (!isset($cart_wrapper->{$field_name})) {
continue;
}
switch ($settings['copy_profiles_source']) {
case 'order':
if (!isset($order_wrapper->{$field_name})) {
continue;
}
$profile_id = $order_wrapper->{$field_name}
->value()->profile_id;
break;
case 'addressbook':
$profile_id = commerce_addressbook_get_default_profile_id($account->uid, $profile_type);
break;
}
if ($profile_id != FALSE) {
$cart_wrapper->{$field_name}
->set($profile_id);
}
}
// Save the $cart_wrapper.
if (isset($cart_wrapper)) {
$cart_wrapper
->save();
}
if ($settings['suppress_cart_messages']) {
$_SESSION['messages']['status'] = $existing_status_updates;
if (isset($_SESSION['messages']['commerce-add-to-cart-confirmation'])) {
unset($_SESSION['messages']['commerce-add-to-cart-confirmation']);
}
}
}
/**
* Form handler: Order reorder form.
*/
function commerce_reorder_reorder_form($form, &$form_state, $order, $settings, $options) {
$form_state['reorder_settings'] = $settings;
$form_state['order'] = $order;
$form_state['reorder_options'] = $options;
$form['submit'] = array(
'#type' => 'submit',
'#value' => isset($options['reorder_button_label']) ? $options['reorder_button_label'] : t('Reorder'),
'#name' => 'reorder-line-item-' . $order->order_id,
'#order_id' => $order->order_id,
);
return $form;
}
/**
* Submit handler: Completes the reorder.
*/
function commerce_reorder_reorder_form_submit(array $form, array &$form_state) {
commerce_reorder_helper($form_state['order'], null, $form_state['reorder_settings']);
drupal_set_message(t('Order copied to your cart.'));
$options = $form_state['reorder_options'];
// Check the redirect option set in the view and where to redirect.
if ($options['redirect']) {
$url = isset($options['redirect_url']) ? $options['redirect_url'] : 'cart';
$url = token_replace($url, array(
'commerce-order' => $form_state['order'],
));
$form_state['redirect'] = $url;
}
}
/**
* Implements hook_forms().
*
* To provide distinct form IDs for reorder forms, the order IDs
* referenced by the form are appended to the base ID,
* commerce_reorder_reorder. When such a form is built or submitted, this
* function will return the proper callback function to use for the given form.
*/
function commerce_reorder_forms($form_id, $args) {
$forms = array();
// Construct a valid cart form ID from the arguments.
if (strpos($form_id, 'commerce_reorder_reorder_') === 0) {
$forms[$form_id] = array(
'callback' => 'commerce_reorder_reorder_form',
);
}
return $forms;
}
Functions
Name![]() |
Description |
---|---|
commerce_reorder_forms | Implements hook_forms(). |
commerce_reorder_helper | Helper function to reorder a previous order. |
commerce_reorder_menu | Implementation of hook_menu |
commerce_reorder_permission | Implementation of hook_permission(). |
commerce_reorder_preprocess_link | Dynamically add a CSRF-protection token to the reorder-links usin a preprocess function. |
commerce_reorder_reorder_callback | Perform the reorder action for the operations menu |
commerce_reorder_reorder_form | Form handler: Order reorder form. |
commerce_reorder_reorder_form_submit | Submit handler: Completes the reorder. |
commerce_reorder_views_api | Implements hook_views_api(). |