Notice: Undefined index: name in commerce_checkout_commerce_order_status_info() (line 281 of /home/quickstart/websites/arbx6.dev/sites/all/modules/commerce/modules/checkout/commerce_checkout.module).

Notice: Undefined index: status_cart in commerce_checkout_commerce_order_status_info() (line 284 of /home/quickstart/websites/arbx6.dev/sites/all/modules/commerce/modules/checkout/commerce_checkout.module).

Comments

chriscalip’s picture

StatusFileSize
new837 bytes

patch available.

rszrama’s picture

Category: bug » support
Status: Active » Closed (works as designed)

Default values for checkout pane info are added in commerce_checkout_pages() for both name and status_cart (and a variety of other attributes). The only odd thing is how you managed to not have them. Perhaps you're altering (or a module is altering) checkout page info arrays in such a way that data is being lost? In any event, it's not a bug in Commerce itself.

blainelang’s picture

Status: Closed (works as designed) » Active

I came across this same issue after adding a HOOK_commerce_checkout_page_info_alter function.

I need to skip one of the checkout workflow stages but only if the cart does not contain a product requiring registration. I can unset the page and not have any notices or errors but as soon as I add the call to load the users cart, the notices appear as reported. Why would that be?

function mymodule_commerce_checkout_page_info_alter(&$checkout_pages) {
  global $user;
  unset($checkout_pages['registration']);
  $cart = commerce_cart_order_load($user->uid);

}
blainelang’s picture

Category: support » bug

Changing this back to bug_report as it appears to be some odd behavior.

rszrama’s picture

Category: bug » support
Status: Active » Closed (works as designed)

Because when you load the cart, it attempts to load the order statuses, but the status associated with the cart is no longer defined if you've unset the checkout page. I'd figure out some other way to skip that page than to unset it. For example, you could just skip the page if unnecessary, as we do on the Payment page.

rszrama’s picture

Sorry, looks like we cross-posted. I don't think this is a bug, just a side effect of removing essential information.

blainelang’s picture

Thanks very much for the quick response Ryan. I get these errors even if I don't unset that page. I don't get the errors when I do unset the page - only if I try to load the cart contents.

Just adding $cart = commerce_cart_order_load($uid) - even for a different user as a test results in these notices, and no other changes to the checkout_pages.

If this is an expected behavior, how would you suggest we disable a checkout page if it's not required?

rszrama’s picture

Honestly, I'm not quite sure. In Commerce 1.x, we just don't have great support for what I'd call "forked paths" in the checkout process. Even for the Payment page, it's a bit of a hack, in that we have a checkout pane form builder function that simply does the automatic redirect to the next page.

I suppose I don't understand why you get the errors if you don't unset the page, though. I'm pretty sure it's cropping up because when you load the cart order it's calling commerce_order_statuses(), which in turn calls a hook implemented by the Checkout module to define checkout page order statuses. I'd throw a debug message in that function to see when it's failing and for what status - i.e. what is the actual index that's not being found.

blainelang’s picture

Ryan,

The issue appears to be in commerce_checkout_commerce_order_status_info function. Normally on viewing the cart, it's called once but when I add the call to commerce_cart_order_load in the HOOK_commerce_checkout_page_info_alter function, it's called a 2nd time (actually before the expected call is done) and the array returned from commerce_checkout_pages is missing variables (array elements) and the notices reported are valid.

It's not related to be unsetting the extra checkout page, the array returned from commerce_checkout_pages just would not contain that page. The issue is the pages that are returned are missing expected elements (variables). There should be 11 or 12 elements in each page array but there are only 2 in the case of the 'checkout' page array.

- See the attached image

rszrama’s picture

Ahh! I see what's happening - we're getting a small bit of recursion it appears. Your code process is something like this:

  1. Request a checkout page URL and the checkout router gets loaded.
  2. The router calls commerce_checkout_pages() to find the current page info array.
  3. That function invokes hook_commerce_checkout_page_info_alter().
  4. In your alter, which happens before checkout page info is cached, you're calling a Cart API function that calls commerce_order_statuses() to find the current user's shopping cart order.
  5. That in turn invokes hook_commerce_order_status_info().
  6. Well, the Checkout module implements this hook and iterates over commerce_checkout_pages() to define order statuses for checkout pages.
  7. And therein lies the recursion and funny business, if I'm not mistaken.

To test my theory, instead of calling commerce_cart_order_load(), just load the order using commerce_order_load(arg(1)) and see what happens.

blainelang’s picture

I added $order = commerce_order_load(arg(1)); instead of the commerce_cart_order_load() function and saw the same result - same notices, and the commerce_checkout_pages looked the same - missing - missing variables.

arg(1) was NULL and I tried again with a valid order id but same result.

blainelang’s picture

Category: feature » support
Status: Needs work » Closed (works as designed)

Ryan,

I've worked around the issue by using HOOK_commerce_checkout_router and now if the cart does not contain an event that requires registration the checkout page is skipped. I believe this is a better solution but it still leaves the reported issue with notices if you try to do add any logic to get order or cart context in the HOOK_commerce_checkout_page_info_alter function.

/**
 * Implements hook_commerce_checkout_router().
 *
 * Skip the registration checkout page unless required.
 */
function my_module_commerce_checkout_router($order, $checkout_page) {
  global $user;

  if ($checkout_page['page_id'] == 'registration' && $user->uid) {
    $registration_required = FALSE;
    $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
    foreach ($order_wrapper->commerce_line_items as $line_item_wrapper) {
      $line_item = $line_item_wrapper->value();
      if ($line_item->line_item_label == 'Conference Attendee') {
        $registration_required = TRUE;
        break;
      }
    }
    if (!$registration_required) {
      $order = commerce_order_status_update($order, 'checkout_' . $checkout_page['next_page'], FALSE, TRUE, t('Conference Registration was skipped - not required for these products.'));
      drupal_goto('checkout/' . $order->order_id . '/' . $checkout_page['next_page']);
    }
  }
}
tmsimont’s picture

Category: support » feature
Status: Closed (works as designed) » Active

patch in #1 works for me.

Doesn't it seem like a good idea to do what patch #1 does and check for essential data before trying to use it? I have quite a few modules that remove checkout pages under certain conditions. So far, this error has been the only negative result of using the page info alter to "fork" the checkout process.

Can #1 or a similar concept be applied so other contrib modules can attempt to "fork" checkouts, at least for as long as the "forking" is not supported in commerce's core?

tmsimont’s picture

Status: Active » Needs review
rszrama’s picture

Status: Needs review » Needs work

Can you review my comments above and see if perhaps you shouldn't be hooking into the router instead also? #10 I believe outlined how there was data missing, but it appeared to be the result of a bit of recursion.

rszrama’s picture

Category: support » feature
Status: Closed (works as designed) » Needs work

fwiw, I recently switched a module from using checkout page alteration to hooking into the checkout router. You can see the code for an example in the Commerce PayPal project, the paypal_ec submodule.

ponies’s picture

#12 works for me!

chriscalip’s picture

Does it mean that api checkout page alteration is deprecated in favor of checkout router api ? If that is the case this this issue is rendered closed as designed and no further effort is needed into this issue.

rszrama’s picture

I'm not sure if deprecated is the right word; I've always imagined one or the other way would work but didn't have to really try it myself until I realized a PayPal Express Checkout using checkout page alteration wouldn't really work. When it comes to arranging alternate checkout flows, yeah, I'd prefer using the checkout router.

chriscalip’s picture

yeah currently doing multi checkout routes depending on role and implemented that through checkout page alteration. ty for the clarification.

dparvanova’s picture

#12 works for me.

How can I remove the "Registration" from the checkout progress block when the registration is skipped? This block is provided by commerce_checkout_progress module

Thanks

RonD’s picture

#12 works for a specific product SKU "if ($line_item->line_item_label == 'Conference Attendee')". So it works for a site with one product needing registration, but requires updating the code anytime a product is added with a different SKU that requires registration.

Is there a way to determine if the product ordered has a "registration" field in the product type or content type? This would negate the need to change code for a new product SKU and make the #12 code work with all products defined in the site needing registration.

blainelang’s picture

@dparvanova, I use HOOK_commerce_checkout_pane_info_alter() and test for the condition I want (items on order etc) and then if I don't want a specific panel to appear then set that pane's enabled flag to FALSE.

Add a dsm($checkout_pane) or your favorite debugging method to see the pane names

function mymodule_commerce_checkout_pane_info_alter(&$checkout_pane) {
  global $user;

  $order = commerce_cart_order_load($user->uid);
    // If we are not in the checkout admin page and we have a valid order
    if(!path_is_admin(current_path()) AND !empty($order)) {
    $order_wrapper = entity_metadata_wrapper('commerce_order', $order->order_number);
    foreach ($order_wrapper->commerce_line_items as $line_item_wrapper) {
        $line_item = $line_item_wrapper->value();
        $product = commerce_product_load($line_item->commerce_product[LANGUAGE_NONE][0]['product_id']);
        if ($product->type == 'sometype') {
            $show_shipping_panes = TRUE;
          }
        }
    }

    if ($show_shipping_panes == FALSE AND isset($checkout_pane['commerce_shipping'])) {
        $checkout_pane['commerce_shipping']['enabled'] = FALSE;
    }
}
lupugabriel’s picture

Initializing values with defaults in hook_commerce_checkout_page_info_alter() worked for me... Hope might be helpful.

function my_module_commerce_checkout_page_info_alter(&$checkout_pages) {
    foreach ($checkout_pages as $count => $checkout_page) {
        if (!isset($checkout_pages[$count]['name'])) $checkout_pages[$count]['name'] = NULL;
        if (!isset($checkout_pages[$count]['status_cart'])) $checkout_pages[$count]['status_cart']  = FALSE;
    }
}
aaronbauman’s picture

Project: Commerce Core » Commerce Rules Extra
Component: Checkout » Code
Category: Feature request » Bug report
Issue summary: View changes
Status: Needs work » Active

I tracked this down to some kind of recursion issue with Commerce Rules Extra

The implementation of hook_commerce_checkout_page_info_alter invokes a rule

    rules_invoke_all('commerce_rules_extra_process_checkout_page');

Is causing some kind of recursion and throwing things for a loop here somehow.

I disabled the 3 commerce rules extra rules, and the notices went away.

perignon’s picture

Status: Active » Closed (won't fix)

Reopen if the issue still exists. Cleaning up the issue queue.

sgdev’s picture

Version: 7.x-1.x-dev » 7.x-2.1

Just adding a comment here for anyone using Commerce Rules Extra 7.x-2.1. If you are running into this problem, upgrade to 7.x-2.x-dev.

I was seeing these errors whenever cache cleared, and realized there was something happening to the $checkout_pages defaults. Whenever I commented out the rules_invoke_all call as mentioned in #25, the errors stopped.

I downloaded 7.x-2.x-dev, looked at the commerce_rules_extra_commerce_checkout_page_info_alter function code, and it has changed significantly. It now sets the $checkout_pages defaults within the function, which makes sense and fixes the issue. There is also this comment included that validates what I was seeing:

    // As of this issue https://www.drupal.org/node/1855900 it can easily happen
    // that this hook is invoked checkout_pages definitions that don't have any
    // defaults set. To avoid notices we set the defaults on our own. The code
    // below has to exactly match what's done in commerce_checkout_pages().