Hey fago and all,

Berdir suggested I create this issue. As I understand it, $user is a wrapped entity. But when testing a chained token with the Userpoints module, I'm experiencing the following problem...

I tried to create a chained token to give me the uid of the user being awarded points. To do this, I tried using the following token:

[userpoints_transaction:user:uid]

But when this token was evaulated, here is what is printed:

Property uid

Thoughts? The corresponding issue in the Userpoints issue queue is here:

http://drupal.org/node/958288

Thanks!

--Ben

CommentFileSizeAuthor
#6 fix_uid_token.patch1.68 KBberdir

Comments

fago’s picture

Title: Chained token doesn't work with wrapped entities » Userpoint transaction chained token issues
Project: Entity API » User Points
Component: Entity property wrapper » Code: userpoints

I don't think this is a general bug, e.g. this code works just fine:

$wrapped_node = entity_metadata_wrapper('node', 1);
$wrapped_entity = entity_metadata_wrapper('entity', $wrapped_node);
echo $wrapped_entity->author->mail->value();

"Property uid" is what you get if you cast the wrapper of the uid property to a string, so I guess that what's happening somewhere. Anyway, from what I've seen from the linked issue you are doing your own token integration, so providing the right values then is up to you. I guess you just did not unwrap the user object before passing it to token system.
FYI, as alternative you could rely on the entity tokens module, which generates tokens for all entity properties declared via hook_entity_property_info().

berdir’s picture

Yes, but I don't know *that* it is a wrapped entity object. I would have to check explicitly. IMHO I shouldn't have to do that. AFAIK, the point of the whole wrapper thing is that they are a drop-in replacement for lazy loading real entities. So it is imho their task to be as compliant as possible to whatever uses them.

I am doing my own token integration because userpoints_transaction is not (yet) an entity. Also, this isn't my own token. It is a user token and I'm just passing that forward to whatever module feels responsible to extract the token.

I'll see if I can come up with a generic example to show the problem. your example directly addresses the object, but the problem appears when using tokens...

berdir’s picture

Title: Userpoint transaction chained token issues » Tokens don't work with wrapped entities
Project: User Points » Entity API
Component: Code: userpoints » Core integration

Ok, here is an example.

$user = entity_metadata_wrapper('user', 1);
print token_replace('User id: [user:uid]', array('user' => $user));

This prints "user id: Property uid". IMHO, this is supposed to work so I'm moving this back to you. If you disagree, then I can implement a workaround.

fago’s picture

Title: Tokens don't work with wrapped entities » Userpoint transaction chained token issues
Project: Entity API » User Points
Component: Core integration » Code: userpoints

>IMHO I shouldn't have to do that. AFAIK, the point of the whole wrapper thing is that they are a drop-in replacement for lazy loading real entities. So it is imho their task to be as compliant as possible to whatever uses them.

Yep, lazy-loading is one of the nice things the wrapper do. Still the wrapper objects are different to the usual entity objects in many ways and don't try or pretend to be usable instead of usual entity objects. Thus, if a API functions expects a real entity object, you cannot pass a wrapper.

>I am doing my own token integration because userpoints_transaction is not (yet) an entity. Also, this isn't my own token. It is a user token and I'm just passing that forward to whatever module feels responsible to extract the token.

Yes, but you need to pass a real user object and not entity wrapper to the token system.

fago’s picture

ops, cross-posted. Anyway, #4 applies to #3 too. :) You need to do:

$wrapper = entity_metadata_wrapper('user', 1);
print token_replace('User id: [user:uid]', array('user' => $wrapper->value()));
berdir’s picture

Status: Active » Needs review
StatusFileSize
new1.68 KB

Ok, got it.

Instead of using the pre-loaded $txn->user object which might be a entity wrapper or not, depending on the context, I'm always using user_load($txn->uid). If it is a real user object, that call should hit the static cache so it should be pretty fast. And if not, I guess that is what $wrapper->value would do anyway.

fago’s picture

Why would there be a wrapper in the token-chain? Usually it isn't, unless you call it that way what I'd say is wrong and should be fixed.

Also I doubt user_load($txn->uid) would work for a wrapper? Even, if there is a defined uid property I doubt it just casts to its integer value. Are you sure might get a wrapper at this point?

berdir’s picture

$txn->user can be a wrapper or not. $txn->uid is always just the user id.

Yes, I do set $txn->user as a wrapper myself, the simple reason for that is that I am passing the $txn object to rules.module and rules then calls token_replace().

berdir’s picture

Status: Needs review » Fixed

Commited the patch above.

@fago: What you're saying makes sense (wrapped entities shouldn't be passed to token_replace()), but rules.module would be responsible for unwrapping them first, I can't do that. I could only stop using entity wrappers completely.

fago’s picture

> What you're saying makes sense (wrapped entities shouldn't be passed to token_replace()), but rules.module would be responsible for unwrapping them first, I can't do that.

If that the case, this is bug we need to fix. In that case, could you create me issue with steps to reproduce it?

Status: Fixed » Closed (fixed)

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