I'd like to see events for "viewing cart" and "viewing (various) checkout pages".

My use case is I want to display a message to the user when viewing their cart, or i want to redirect them somewhere if they don't have a particular product in their cart and they try to checkout. However, I could see lots of other possible uses for such events.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

AaronBauman’s picture

Status: Active » Needs review
FileSize
2.72 KB

This patch adds the following events, which are hopefully self-explanatory:

  • "When viewing Shopping Cart"
  • "When viewing checkout page "Checkout""
  • "When viewing checkout page "Complete""
  • "When viewing checkout page "Payment""
  • "When viewing checkout page "Review""
Strae’s picture

Subscribe, those events are very useful to implement a custom-rule based shipping costs, for example.

I applied the patch to commerce_kickstart profile, all seem ok for now.

Strae’s picture

I tryed the "When viewing checkout page "Review"", it works;
But with "When viewing Shopping Cart" the event is triggerd after the main content is rendered, so if for example I add/remove line items in this step, the "your cart" block get updated with the edits, but not the "shopping cart contents" block (that is the main content).

So i added "Before viewing Shopping Cart" event that get invoked in line 37 of commerce_cart.pages.inc and it works

function commerce_cart_view() {
  global $user;
  // Invoke the cart before view event. 
  // Move this alter 'if ($order = commerce_cart_order_load($user->uid)) {'  if need to invoke the event only when the cart exist.
  rules_invoke_all('commerce_cart_cart_view_before');
  // Default to displaying an empty message.
  $content = theme('commerce_cart_empty_page');

  // First check to make sure we have a valid order.
  if ($order = commerce_cart_order_load($user->uid)) {
    $wrapper = entity_metadata_wrapper('commerce_order', $order);

    // Only show the cart form if we found product line items.
    if (commerce_line_items_quantity($wrapper->commerce_line_items, commerce_product_line_item_types()) > 0) {

      // Add the form for editing the cart contents.
      $content = commerce_embed_view('commerce_cart_form', 'default', array($order->order_id), 'cart');
    }
  }

  // Invoke the cart view event with the current order.
  rules_invoke_all('commerce_cart_cart_view', $order);

  return $content;
}

(sorry if i dont provide a patch, i dont know how to make it)

pun_pun’s picture

Thank you!!! Now I can sleep calm ))

I've made a total order weight calculation, based on your events. So if you are interested - you are welcome. :)

rszrama’s picture

Status: Needs review » Closed (won't fix)

While I understand the reason behind the patch, I'm not sure I can support such a patch going into core - I'm not even sure using Rules for this sort of task (or the related "Content is being viewed" event) is a good idea.

The problem in our case is that it isn't dependable. For example, someone may be embedding the checkout form somewhere else or just using Views to create the shopping cart display (there's a recipe for that here in the queue). I do appreciate the time you've put into making this sharable, though!

For now my recommendation is to maintain a patched version of Commerce using the patch above or consider making it a separate module (or part of another module if a related one exists).

AaronBauman’s picture

Makes sense.
Thanks for the explanation, Ryan.

AaronBauman’s picture

Issue summary: View changes

necro-post, since i came across the need for this again.
all of this is super easy to put into a module, except for "viewing cart":

function EXAMPLE_MODULE_rules_event_info() {
  $checkout_pages = commerce_checkout_pages();
  foreach ($checkout_pages as $page) {
    $events['commerce_checkout_page_' . $page['page_id']] = array(
      'label' => t('When viewing checkout page "!page"', array('!page' => $page['name'])),
      'group' => t('Commerce Checkout'),
      'variables' => array(
        'commerce_order' => array(
          'type' => 'commerce_order',
          'label' => t('Shopping cart order'),
        ),
      ),
      'access callback' => 'commerce_order_rules_access',
    );
  }
  return $events;
}

function EXAMPLE_MODULE_commerce_checkout_router($order, $checkout_page) {
  rules_invoke_all('commerce_checkout_page_' . $checkout_page['page_id'], $order);
}

Andrew211’s picture

Cart page is easy too, here's da code if anyone want's it.

Let's call the module "checkout_events"

checkout_events.rules.inc

<?php
function checkout_events_rules_event_info() {
  $checkout_pages = commerce_checkout_pages();
  foreach ($checkout_pages as $page) {
    $events['commerce_checkout_page_' . $page['page_id']] = array(
      'label' => t('When viewing checkout page "!page"', array('!page' => $page['name'])),
      'group' => t('Commerce Checkout'),
      'variables' => array(
        'commerce_order' => array(
          'type' => 'commerce_order',
          'label' => t('Shopping cart order'),
        ),
      ),
      'access callback' => 'commerce_order_rules_access',
    );
  }
  
  $events['commerce_checkout_page_view_cart'] = array(
    'label' => t('When viewing page "!page"', array('!page' => 'View Cart')),
    'group' => t('Commerce Checkout'),
    'variables' => array(
      'commerce_order' => array(
        'type' => 'commerce_order',
        'label' => t('Shopping cart order'),
      ),
    ),
    'access callback' => 'commerce_order_rules_access',
  );
  return $events;
}

And in checkout_events.module

<?php
function checkout_events_commerce_checkout_router($order, $checkout_page) {
  rules_invoke_all('commerce_checkout_page_' . $checkout_page['page_id'], $order);
}

function checkout_events_preprocess_page(){
  global $user;
  
  if(arg(0) == 'cart' && arg(1) == NULL){
    rules_invoke_all('commerce_checkout_page_view_cart', commerce_cart_order_load($user->uid));
  }
}
sorabh.v6’s picture

Hi Guys,

I was facing the same issue as well but for the newer version this patch wasn't working, so I rerolled the patch. Attaching the latest patch and interdiff file.

Thanks guys

sorabh.v6’s picture