I have a membership product with several options depending on length of membership. I've created different SKUs for these options in Adjustments and a separate role assignment feature for each of them. But the role is not assigned when I buy either of these products. On Features screen, SKUs for these role assignments are listed incorrectly, looks like this may be the problem. I've browsed the code but so far haven't been able to find out where these model numbers are coming from came from.

Comments

julia_g’s picture

OK, I've figured out what's going on.
My adjustment SKUs are all numeric. The function array_merge_recursive in module_invoke_all takes the correct model array and merges it with empty array, and in the process numeric keys are lost and start with 0. See comments at http://us.php.net/manual/en/function.array-merge-recursive.php .

I've solved the problem by adding letters to my SKUs, but someone may want to write a patch to avoid this issue.

julia_g’s picture

This may cause problems in other modules, so I'll resubmit is as Drupal core bug.

Island Usurper’s picture

Status: Active » Postponed (maintainer needs more info)

I don't really think Drupal is wrong to use array_merge_recursive() in module_invoke_all(). It's behavior with numeric keys is well known and documented, so we should be able to work around it. Where is this call to module_invoke_all() where the SKUs are used as keys?

cha0s’s picture

Title: Role problem with several options for one product » Numeric keyed SKUs handled improperly by hook_uc_product_models().
Assigned: Unassigned » cha0s
Status: Postponed (maintainer needs more info) » Needs review

I have identified the problem, and offer a solution.

hook_uc_product_models() has been updated. Now, you do not map the array keys to the values here. You just create an array of values, and return that. The work of mapping the values to respective keys is now handled by uc_product_models(), using drupal_map_assoc().

On top of that fix, I also organized the logic better, so that any model that comes before 'Any' alphabetically won't supplant it as the first option.

Added an entry in hooks.php as well, noticed there was no doc of this (new) hook yet.

cha0s’s picture

StatusFileSize
new2.39 KB

Er, oops. :)

Island Usurper’s picture

Status: Needs review » Needs work

Actually use "hook_uc_product_models()" in hooks.php. This keeps api.module from getting confused with two functions of the same name, and people will actually search for "hook_". Keep the actual code from uc_attribute_uc_product_models() as an example, though.

cha0s’s picture

Status: Needs work » Needs review
StatusFileSize
new2.43 KB

Good call, missed that one.

Island Usurper’s picture

Status: Needs review » Fixed

Looks good. Committed.

Status: Fixed » Closed (fixed)

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

hanoii’s picture

Status: Needs review » Active
StatusFileSize
new500 bytes

Sorry to bring this one up to life, but I have found a problem in the committed patch, causing a bug which have been annoying me for a while and now I was able to locate the problem, which pointed me to this issue after some search.

I was noticing that with certain combinations of SKU I was always missing one on the STOCK edition page.

The patch should be self-explanatory, but to explain what I found:

Say you have a product with its main SKU = 2
Then you have a Color attribute with three different colors and its respective SKU adjustments:

BLUE: 2b
RED: 2r
YELLOW:2y

Then if you go to the stock edition screen, you won't three the four SKUs (main + 3 from colors), but you would see only three (main + two of the adjustments). I first figured that this was intentionally but then, and while working with my uc_out_of_stock module I found it's not. The problem is that the uc_product_get_models() that was improved by this patch is not expecting an associative array from $models = module_invoke_all('uc_product_models', $node); but rather a linear one, but after invoking that hook, there's a line who arbitrary changes the array using the $node->model as a key for the array. As in this case, $node->model would be 2, what's really happening is that it's overwriting the second item of the array, thus, loosing one of the adjustments.

My proposed solution should not mess anything as drupal_map_assoc() below should do the same but properly.

Anyway, patch attached with just one line changed which I think solve this.

hanoii’s picture

Version: 6.x-2.0-beta3 » 6.x-2.0-rc3
Status: Closed (fixed) » Needs review
Island Usurper’s picture

Status: Active » Closed (fixed)

It looks like that change has already been done: #479856: Stock table missing SKUs