It seems that most of the "Cart Item" events/triggers dont work with rules and ubercart.

This is a test rule that I made:

{ "rules_alter_product_quantity" : {
"LABEL" : "TEST UBERCART RULE",
"PLUGIN" : "reaction rule",
"REQUIRES" : [ "rules", "entity" ],
"ON" : [ "uc_cart_item_insert", "uc_cart_item_delete" ],
"DO" : [ { "drupal_message" : { "message" : "IT WORKS!" } } ]
}
}

It shows the message when I delete a cart item, but not when I add a cart item. Same thing for the debug log. It appears when I delete an item, but not when I add it.
I have the same problem even with uc_cart_item_update and uc_cart_item_presave

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

SilviuChingaru’s picture

I can confirm that only uc_cart_item_delete event is triggered.

The events are implemented by entity module so this issue is an entity module issue.

Moved here: #1516106: Rule events set by entity_rules_event_info() not triggering...

SilviuChingaru’s picture

Status: Active » Closed (duplicate)
longwave’s picture

I think this is because Entity API automatically provides those events, but Ubercart doesn't fully implement Entity API when creating and updating cart items. This should probably be fixed in Ubercart, and/or an option added to Entity API hooks to say "don't create event triggers".

SilviuChingaru’s picture

As far as I can see in function entity_rules_event_info() if we set $configuration to TRUE the event is not implemented by entity API...

I think we should look at commerce_product.controller.inc from commerce module to implement UcOrderProductController correctly. Don't you?

longwave’s picture

Status: Closed (duplicate) » Active
SilviuChingaru’s picture

Version: 7.x-3.x-dev » 7.x-3.0
Status: Needs review » Active
FileSize
2.19 KB

This is a rudimentary fix but it works. I think the code need to be polished but it works for all uc_cart_item events and no change in functionality... I don't know if the following line should be removed:

module_invoke($data['module'], 'uc_update_cart_item', $node->nid, $data, min($qty, 999999), $cid);

but there is no problem if it shouldn't...

Waiting for suggestions...

SilviuChingaru’s picture

Status: Active » Needs review
longwave’s picture

Version: 7.x-3.0 » 7.x-3.x-dev

Patches need to be against 7.x-3.x-dev for testbot to test them.

SilviuChingaru’s picture

I think the test bot doesn't test patches because of this:
#1487002: Patch is picked up by the queue but not tested (according to #12 Ubercart 7.x-3.x branch should pass all the tests before any patches are tested)
or of this
http://qa.drupal.org/pifr/test/132134

From Testbot FAQ:

  • Why is my patch marked "postponed"? Most of the time this is because the branch you're testing against hasn't passed tests. Follow the "branch" link on the qa.drupal.org page explaining that your patch is postponed and you'll see the status of branch testing. Usually some work is required on the branch (and tests won't succeed without new commits).

Distinct issue here: #1517564: uc_credit tests fail in 7.x on testbot

SilviuChingaru’s picture

Status: Needs review » Needs work
SilviuChingaru’s picture

Status: Needs work » Needs review
SilviuChingaru’s picture

Version: 7.x-3.0 » 7.x-3.x-dev
Status: Active » Needs review
FileSize
2.19 KB

Reposted patch to see if it pass or Postponed.

SilviuChingaru’s picture

@denisr does last patch fixed the problem?

longwave’s picture

I made a start on reviewing this but realised we should have tests for the cart, so I started work on that: #1576894: Improve cart tests and API

I think we also need tests for uc_product_kit as that relies on functionality that is changed by this patch, and we should prove it works before and afterwards.

longwave’s picture

#12: ubercart-uc_cart-1492626-1.patch queued for re-testing.

Feet’s picture

The patch in #12 gets the 'After saving a new cart item' event working for me. Nice.

Still no love from 'After updating an existing cart item'.

EDIT: To clarify, 'After updating an existing cart item' works for deleting an item or adding a new one but not updating the quantities within the cart page. Cheers

Feet’s picture

Double up, sorry.

Feet’s picture

Is it possible to trigger an event when updating the qty in the cart?

I had thought that's what Cart Item - 'After updating an existing cart item' would do.
But now wonder if that's just a trigger for when an item which is already in the cart is added again. Is that right?

If so is there a way to trigger an event for updating the cart?
I'm guessing it would be in uc_cart_view_form_submit in uc_cart.module (line 718 ish)
By adding hook_rules__event_info and rules_invoke_event but I am perplexed why the other Cart Item events aren't in uc_cart.rules.inc

Can someone help to clarify where I'm going wrong?

Feet’s picture

For my case I created an event in uc_cart.rules.inc at line 24

  $events['uc_cart_qty_updated'] = array(
    'label' => t('Customer updates quantity in cart'),
    'group' => t('Cart'),
    'variables' => array(
      'cart_id' => array(
        'type' => 'text',
        'label' => t('cart ID'),
      ),
    ),
  );

and invoked it in uc_cart.module at line 718

      $cartID = $form['items'][0]['#entity']->cart_id;
      rules_invoke_event('uc_cart_qty_updated', $cartID);

Which works for me

longwave’s picture

#12: ubercart-uc_cart-1492626-1.patch queued for re-testing.

longwave’s picture

#12: ubercart-uc_cart-1492626-1.patch queued for re-testing.

We have a bunch of product kit tests now, so let's see what happens.

DanZ’s picture

See #1884512-22: Make ordered products entity fieldable. Since UcCartItemController extends UcOrderProductController, this will enhance cart items, too. It has the potential to add the proper rules events. This is via EntityAPIController::invoke(), which is called for create, update, pre-save, and delete:

  // Invoke rules.
  if (module_exists('rules')) {
    rules_invoke_event($this->entityType . '_' . $hook, $entity);
  }

The current code largely bypasses the EntityAPIController, which means that these events sometimes don't get invoked. The patch for the issue above runs everything through the controller, so maybe that technique would help.

Looking at uc_cart_module, there are all sorts of db_update(), db_insert(), db_delete() and db_query() calls on the {uc_cart_products} table. Direct database manipulation bypasses the Entity API and does not invoke Rules events. Ideally, they would all be replaced by calls to entity_load(), entity_save(), and entity_delete(), possibly in wrapper functions. That would ensure that all the rules get invoked properly by way of EntityAPIController. The patch in #12 does take care of some of this, but not all.

Note that using EntityAPIController also provides hooks which could be documented in the API. See http://drupal.org/node/999938.

longwave’s picture

This is #12 with added tests, which prove the issue noted in #16/18.

I think we can make the cart item controller a bit more intelligent about removing items when they are "updated" to a quantity of 0, and perhaps also remove hook_uc_update_cart_item().

Status: Needs review » Needs work

The last submitted patch, 1492626-uc_cart_item-entity-23.patch, failed testing.

longwave’s picture

Status: Needs work » Needs review
FileSize
9.65 KB

In this patch, the cart item controller is responsible for $item->changed and also removing an item when the quantity drops to 0. hook_uc_update_cart_item() is still needed to handle product kits.

longwave’s picture

This patch adds basic documentation for the cart item entity hooks.

DanZ’s picture

uc_cart.module has seven database operations on the {uc_cart_products} table. This patch turns four into entity operations. Should they all be changed to entity operations?

longwave’s picture

Of the remaining three, two are in uc_cart_cron(), to discover abandoned cart IDs. These cart IDs are then passed to uc_cart_empty() which uses entity_delete_multiple(). We could switch to EntityFieldQuery() to discover the cart IDs but I don't see any benefit in doing so.

The other is in uc_cart_login_update() where anonymous and authenticated carts are merged. This is arguable, although I guess as the insert/update half of the merge operation will fire the entity hooks, I guess the delete half should do the same. It looks like we could just switch to uc_cart_empty() here instead of deleting the cart items directly.

longwave’s picture

Let's see what testbot thinks of changing uc_cart_login_update().

longwave’s picture

And let's see what happens if we combine this with the latest patch from #1884512: Make ordered products entity fieldable

Status: Needs review » Needs work

The last submitted patch, 1492626-1884512-entity-combined.patch, failed testing.

longwave’s picture

Status: Needs work » Needs review
FileSize
39.88 KB
longwave’s picture

Status: Needs review » Fixed

Committed #29.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

Anonymous’s picture

Issue summary: View changes

I exported the rule, so it can be easier to understand