You are here

function commerce_checkout_page_access in Commerce Core 7

Checks access to a particular checkout page for a given order.

Parameters

$checkout_page: The fully loaded checkout page object representing the current step in the checkout process.

$order: The fully loaded order object represented on the checkout form.

Return value

TRUE or FALSE indicating access.

1 call to commerce_checkout_page_access()
commerce_checkout_router in modules/checkout/includes/commerce_checkout.pages.inc
Redirects invalid checkout attempts or displays the checkout form if valid.

File

modules/checkout/commerce_checkout.module, line 789
Enable checkout as a multi-step form with customizable pages and a simple checkout pane API.

Code

function commerce_checkout_page_access($checkout_page, $order) {

  // Load the order status object for the current order.
  $order_status = commerce_order_status_load($order->status);
  if ($order_status === FALSE) {
    return FALSE;
  }

  // If the order is not in a checkout status, return FALSE for any page but the
  // completion page unless the order is still a shopping cart.
  if ($order_status['state'] != 'checkout' && $checkout_page['page_id'] != 'complete') {
    if ($order_status['state'] == 'cart') {
      $checkout_pages = commerce_checkout_pages();
      $first_page = key($checkout_pages);
      if ($checkout_page['page_id'] != $first_page) {
        return FALSE;
      }
    }
    else {
      return FALSE;
    }
  }

  // If the order is still in checkout, only allow access to pages that it is
  // currently on or has previously completed.
  if ($order_status['state'] == 'checkout') {
    $status_checkout_page = commerce_checkout_page_load($order_status['checkout_page']);

    // This is the page the user is currently on.
    if ($status_checkout_page['page_id'] == $checkout_page['page_id']) {
      return TRUE;
    }

    // Prevent access to later steps of the checkout process.
    if ($checkout_page['weight'] > $status_checkout_page['weight']) {
      return FALSE;
    }

    // Check that there are back buttons in every pages between the current
    // page and the page the user wants to access.
    $pages = commerce_checkout_pages();
    $current_page = $status_checkout_page;
    do {
      if (!$current_page['buttons']) {
        return FALSE;
      }

      // Look for a previous page ID.
      $prev_page_id = $current_page['prev_page'];

      // If we cannot find one, do not allow access to the current page, causing
      // a redirect to the order's current status. This edge case will occur
      // when a checkout page is removed and a user tries to access an earlier
      // page for an order that was set to the removed page's status.
      if (empty($prev_page_id)) {
        return FALSE;
      }
      $current_page = $pages[$prev_page_id];
    } while ($current_page['page_id'] != $checkout_page['page_id']);
  }
  elseif ($checkout_page['page_id'] == 'complete') {

    // Don't allow completion page access for orders in the cart or canceled states.
    if (!commerce_checkout_complete_access($order)) {
      return FALSE;
    }
  }
  return TRUE;
}