Problem/Motivation

Creating a cart programatically results in this:

EntityMetadataWrapperException: Unknown data property commerce_coupons. in EntityStructureWrapper->getPropertyInfo() (line 335 of sites/all/modules/contrib/entity/includes/entity.wrapper.inc).

Proposed resolution

Check to see if the property exists before trying to use it.

Remaining tasks

User interface changes

API changes

Comments

joelpittet’s picture

Priority: Normal » Major
Status: Active » Needs review
StatusFileSize
new1.42 KB

Status: Needs review » Needs work

The last submitted patch, 1: 2444703-1.patch, failed testing.

dpolant’s picture

Status: Needs work » Postponed (maintainer needs more info)

I'm not so sure about this. If commerce coupon installed correctly, you should definitely have a coupon reference field on all order bundles and this error should not be happening. Did you install Coupons 2.x from an upgrade or from scratch? Were there any problems during installation/upgrade?

joelpittet’s picture

Status: Postponed (maintainer needs more info) » Needs work

@dpolant it happens only when I create a cart programmatically. No problems with the upgrade/install.

Looks like this needs a re-roll.

joelpittet’s picture

I think it only needs a re-roll because there were lots of end of line whitespace errors in the last set of commits.

joelpittet’s picture

Issue summary: View changes
joelpittet’s picture

Status: Needs work » Needs review
StatusFileSize
new1.48 KB

Re-rolling and slight change to the rules isset() EMW checks.

Used -w flag in git diff because there are lots of ending whitespace issues my editor tries to fix.

joelpittet’s picture

Priority: Major » Normal

@dpolant Any chance you'd consider adding tests? I may be able to write one to show this bug. Setting to priority to normal because I don't see others running into this and it was only my quick programmatically generated cart scripts that were throwing this error.

Status: Needs review » Needs work

The last submitted patch, 7: 2444703-7.patch, failed testing.

joelpittet’s picture

Status: Needs work » Needs review
StatusFileSize
new1.49 KB

Ok clean git patch... *shakes fist at testbot*

id.tarzanych’s picture

Added code protections to commerce_order_update in commerce_coupon_usage module
That also causes

Unknown data property error

when Before saving a commerce order Rules event is invoked

joelpittet’s picture

  1. +++ b/commerce_coupon.module
    @@ -1254,9 +1254,6 @@
    -  if (!isset($order_wrapper->commerce_coupons) || !$order_wrapper->commerce_coupons->value()) {
    -    return;
    -  }
    
    @@ -1362,6 +1359,9 @@
    +  if (!isset($order_wrapper->commerce_coupons) || !$order_wrapper->commerce_coupons->value()) {
    +    return;
    +  }
    

    Why does the interdiff show this moved?

  2. +++ b/commerce_coupon.rules.inc
    @@ -111,17 +111,17 @@
    +  $has_coupons = $discount_wrapper->coupon_count->value();
    +  ¶
    +  if ($order_wrapper->commerce_coupons->value()) {
    

    nit: Extra whitespace.

  3. +++ b/modules/usage/commerce_coupon_usage.module
    @@ -405,7 +405,8 @@ function commerce_coupon_usage_commerce_order_update($order) {
    +      $no_coupons = empty($order->original) || !$unchanged->commerce_coupons->value();
    
    @@ -421,18 +422,20 @@ function commerce_coupon_usage_commerce_order_update($order) {
    +    if (!empty($order->original)) {
    ...
    +  elseif (!empty($order->original) && in_array($unchanged->status->value(), $statuses)) {
    

    What is $order->original? I've not seen that in my travels yet.

joelpittet’s picture

Issue tags: +Commerce Sprint
torgospizza’s picture

@joel: It looks like $order->original is created during a status update. See comments for commerce_order_status_update():

/**
 * Updates the status of an order to the specified status.
 *
 * While there is no explicit Rules event or hook devoted to an order status
 * being updated, you can use the commerce_order_update event / hook to check
 * for a changed order status by comparing $order->original->status to the
 * $order->status. If they are different, this will alert you that the order
 * status for the given order was just changed.
 *
joelpittet’s picture

@torgosPizza and @id.tarzanych so I'm saying that may be unnessasary for the scope of this issue.

Maybe the interdiff is weird but I don't think those changes are necessary and I can't see anything in #11 that I'd keep. I could be wrong though.

joelpittet’s picture

StatusFileSize
new1.49 KB

Ok reposting #10 so we can get reviews there. It's fairly quick fix. If the ->original stuff needs to be taken care of maybe it can be in a new issue so this is easier for people to review.

@id.tarzanych feel free to disagree, I'm just trying to finish this issue up to move forward an inch.

Status: Needs review » Needs work

The last submitted patch, 16: 2444703-10.patch, failed testing.

torgospizza’s picture

I was able to apply the patch manually and the concept seems to work well. Might need a re-roll though.

Related is this #2362799: Clarify and strengthen the logic when checking an order for coupons which may become a duplicate if this patch ends up solving that problem as well.

joelpittet’s picture

Status: Needs work » Needs review
StatusFileSize
new9.58 KB

Apparently HEAD has moved.

Ensuring all the usages of coupon_count and loops through $order_wrapper->commerce_coupons are checked.

I see a bit more what @id.tarzanych was trying to do. I refactored that a bit to make it a bit more clear to that point (I hope).

joelpittet’s picture

Status: Needs review » Needs work
+++ b/commerce_coupon.module
@@ -773,16 +773,13 @@ function commerce_coupon_redeem_coupon_code($code, $order, &$error) {
-    foreach ($order_wrapper->commerce_coupons as $order_coupon_wrapper) {
...
+    if (commerce_coupon_order_has_coupon_code($coupon->coupon_id, $order)) {

Also, there was a bit of duplicate logic happening here for checking if a coupon. But I got that wrong. New patch coming a sec. But curious to know if checking the coupon code can be considered the same as checking the coupon_id?

joelpittet’s picture

Status: Needs work » Needs review
StatusFileSize
new19.48 KB
new703 bytes

Fixed logic

nvahalik’s picture

Status: Needs review » Needs work

Joel, in #22, your patch has patches in it.

joelpittet’s picture

Status: Needs work » Needs review
StatusFileSize
new9.57 KB

Whoops, was rushing out the door, apparently I'm not setup to do non-core:P

Now with less patch!

dpolant’s picture

Status: Needs review » Fixed

OK, to summarize:

- There seems to be some consensus that there is a possible case where the order object does not have the commerce_coupons field.
- As torgos mentioned, it could be related to https://www.drupal.org/node/2362799 which is a case about using multiple order bundles (among other things).

Joel's patch seems generally good but it is a large diff. As I looked at it, I think it goes a bit too far in terms of adding protections that in many cases we don't need. Here's a breakdown:

- Checking for commerce_coupons field on the order is good. My commit leaves all of these in.
- Checking for coupon_count on discounts should not be necesssary. I add this property directly to all discount entities: it should always be available and should never throw a wrapper error.
- Checking for $form_state['coupons'] in the discount admin function should not be necessary either. The thinking is that if the coupons module is on, it should always be doing its thing on the discount form.

I'll leave this issue open so anyone grab the latest dev and make sure that it solves their problems. Thanks for the feedback everyone!

  • dpolant committed a46b4e4 on 7.x-2.x
    Issue #2444703 by joelpittet, id.tarzanych:...

Status: Fixed » Closed (fixed)

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