You are here

commerce_reorder.module in Commerce Reorder 7

Same filename and directory in other branches
  1. 7.2 commerce_reorder.module

Allows users to create a new order from their order history.

File

commerce_reorder.module
View 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;
  }
  commerce_reorder_helper($order);
  drupal_set_message(t('Order copied to your cart.'));

  // Redirect to the checkout with the new cart.
  drupal_goto('cart');
}

/**
 * Helper function to reorder a previous order.
 *
 * @param object $order
 *   The commerce_order object to reorder.
 * @param object $account
 *   The user account to assign the order to.
 * @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, $account = 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,
  );
  if (!isset($order)) {
    return;
  }
  if (empty($account)) {
    global $user;
    $account = $user;
  }

  // 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($account->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($account->uid);
      $cart_wrapper = entity_metadata_wrapper('commerce_order', $cart);
    }
    $field_name = 'commerce_customer_' . $profile_type;
    if (isset($order_wrapper->{$field_name}) && isset($cart_wrapper->{$field_name})) {
      $cart_wrapper->{$field_name}
        ->set($order_wrapper->{$field_name}
        ->value()->profile_id);
    }
  }
  if (isset($cart_wrapper)) {
    $cart_wrapper
      ->save();
  }
}

Functions

Namesort descending Description
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_views_api Implements hook_views_api().