Add profile support
smk-ka - March 7, 2007 - 17:58
| Project: | Token |
| Version: | 6.x-1.12 |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | needs review |
Description
The title says it all: a small patch and an include file to support profile.module.
Requires this patch to properly function.
--
Stefan Kudwien
www.unleashedmind.com
| Attachment | Size |
|---|---|
| token-profile-support.patch | 979 bytes |

#1
1. Rename to token_profile.inc
2. Put in token folder
#2
I'm concerned that the method used here would be very expensive -- it might be useful to put them in an explicit 'profile' token domain rather than the general 'user' domain. Ideally, I'm trying to move away from sticking piles of .inc files into the token project itself, as modules can support tokens directly, but since profile.module is in core that's not going to happen. I'll ponder it and see if there's a way to keep things speedy. If you have any ideas on that, definitely chime in!
I am, though, committing the patch for the recursive array merging. It's a must-have. Thanks!
#3
I'd be okay with a separate 'profile' domain, if we can somehow add support for multiple $types and $objects in token_replace() and token_get_values(). That would ease the merging of results coming from multiple domains. (In fact, as I am in the process of switching invite.module to make use of tokens, this missing functionality forced me to do lots of copy 'n paste...)
What I'm thinking of is changing those two parameters to accept either single values or arrays, possibly in several combinations similar to PHP's str_replace():
- string, object (legacy - one domain, one object)
- array, array (multiple domains with matching number of objects)
- array, object (multiple domains using always the same object)
That would allow us to handle multiple domains efficiently. What do you think?
#4
Hmmmm. That's an interesting idea. I'd feel more comfortable using keyed arrays rather than 'matching' arrays... something like:
token_replace('[token] string [another-token]', array('node' => $node, 'user' => $user);
This wouldn't be as cleanly forward-compatible, unfortunately. Perhaps providing a wrapper function -- token_replace_multiple() or something like that -- would be the best approach? Behind the scenes, it would be almost exactly the same, but the compatibility would be cleaner...
Thoughts?
#5
I am continuing the multiple types question over here because it has nothing to do with profile support.
However, I'd still like to see profile support get in, and discuss any performance issues separately. With the perspective of supporting multiple types, I've moved profile fields into their own type.
The drawback of this solution is, that it will be harder to handle for third-party developers. They now have to explicitly include the type 'profile', whereas before it was sufficient to include the domain 'user', that is, token.module handled the inclusion of dependent types belonging to a domain (though not very smart performance-wise).
It probably would be best to have an identifiable domain in the token ([user: id]), which would allow us to load values on demand (think of preg_replace_callback()) rather than having to prepare all associated values in advance. But that's another story...
#6
The above blah blah should have been accompanied by a modified profile patch, so here it is. Patch is against CVS DRUPAL-5.
#7
Re-rolled patch against current DRUPAL-5 branch.
#8
+1 for this feature since there are already related issues that would benefit from it, f.e. personalizing Simplenews newsletters.
#9
I think it should be in the 'user' token domain, because if you load a user object using
user_load()it will have the profile properties as well. Soprofile_token_values()would be something like:<?php
/**
* Implementation of hook_token_values()
*/
function profile_token_values($type, $object = NULL) {
$values = array();
if ($type == 'user') {
static $fields = array();
if (empty($fields)) {
$result = db_query('SELECT name, type FROM {profile_fields}');
while ($field = db_fetch_object($result)) {
$fields[$field->name] = $field;
}
}
if (isset($object)) {
$account = $object;
}
else {
global $user;
$account = $user;
}
foreach ($fields as $name => $field)
$field->value = $account->$name;
if (_profile_field_serialize($field->type)) {
$field->value = unserialize($field->value);
}
$values[$field->name] = _profile_token_format_field($field);
}
}
return $values;
}
?>
I'm going to work on a patch.
Comments?
#10
As promised, here is the patch.
#11
Ops, I mean HERE is the patch :).
#12
Changed
profile_token_list()function so it makes use of_profile_token_profile_fields()too.#13
Sorry, needs review.
#14
Just a sidenote:
The Personalized e-mail project contains a patched token_user.inc that has support for Profile and Nodeprofile modules. Contrary to my former patches, it takes the same approach as recidive's latest efforts, ie. profile/nodeprofile tokens are put in the user domain (where they actually belong).
#15
The problem with "where they actually belong" is performance...
Has anyone done benchmarks on this?
#16
would this work for 6x? if not, any plans for token to support profile fields in 6x?
#17
Can someone point me in the right direction for how to properly benchmark this? I'd be glad to help with testing / coding, as this is a feature I really need so Signup can use real names instead of usernames in salutations.
This patch still applies cleanly and does work from a functional level.
Thanks,
--Andrew
#18
From the handbook: http://drupal.org/node/79237
"How to benchmark Drupal Code"
Thanks for offering to benchmark this, it would be great to include this functionality.
#19
Ok, I finally managed to get some benchmarks done. It looks like there is no noticeable difference in performance. The steps I followed:
$q = "SELECT uid FROM {users} WHERE uid > 1";
$r = db_query($q);
$q = "INSERT INTO {profile_values} VALUES('%d', '%d', '%s')";
$i = 0;
while ($uid = db_result($r, $i++)) {
for ($fid = 1; $fid <= 5; $fid++) {
$v = time();
db_query($q, $fid, $uid, $v);
}
}
I've attached the results, which are virtually identical. If we want more stress testing with *lots* of profile fields, I can do it, but I doubt there will be any issues given the attached results.
--Andrew
#20
@deviantintegral - thank you very much for this detailed work. I'll try to test this and confirm the benchmark in the next few days at which point I would have to agree - let's add it.
#21
Hi,
Could someone tell me what should be the exact syntax to point to a specific profile field value ? To make things clear :
- I used the "profile" module to create a "real name" field that users fill in when they register.
- I changed the username to display this field value.
- I've installed nodeprofile to create "public profiles" for other users. As you may know this module creates specific nodes used as user profiles.
- I'm using auto_nodetitle to automatically replace this node's title with the value of the "real name" field I created in first step (name is profile_pseudo).
- I replaced the standard token_user.inc file with that included in the Personalized mail module, as it is supposed to let me point to the profile & nodeprofile field values.
Unfortunately, when I type "[profile_pseudo]" in the automatic title generation field, it does not work.... Help please !
#22
I succeeded... If anyone's interested, I just inserted the following code :
"
<?phpglobal $user;
if ($user->uid) {
$user = user_load(array('uid'=>$user->uid)); // make sure to assign the returned value.
print($user->profile_pseudo);
}
?>
in the PHP argument textbox.
#23
very intresting
#24
Updated patch.
#25
Patch for version 6. Untested.
#26
What's the status of this issue and the actual possibility of this getting into token's module? I had a stalled project related to this and now I am bringing it up to life again. My main objective is to have a working module for that would let me personalize newsletters (there's been a reference to that issue as well in this thread) and I built a token_profile module that does something very similar to what recidive's patch does. Actually I haven't got that far as to properly support all the profile fields format as he did.
I was thinking if uploading both modules (token_profile and simplenews_token) one I have them completed but was wondering if I should do that if there's plan to follow this issue into token's core.
There's also something else in my mind and that's a default replacement text for empty profile fields, as you can imagine, this is very useful but very specific to newsletters, but, by working this into a module, I can have a bit of a freedom and I was thinking in providing a helper module which would let you configure a default replacement for your profile fields. In that case, I'll need to do the profile replacement in a specific module.
What do you think of uploading it anyway?
#27
@hanoii - I'd say that the status is we need a review of the latest 5.x and 6.x versions uploaded by recidive.
@recidive - I assume this is a re-roll of your patch in #12. Thanks for your help with this!
#28
@hanoii - Also, your use of profile tokens seems very specific and therefore it might not be useful for general use.
#29
@greggles, yes, this is a re-roll.
#30
It certainly pretty specific what I wanted to do, actually I changed my mind and I am thinking in creating a custom token modules that would let user add custom tokens with PHP support for any complex replacement.
I have applied #24 and tested it a little bit and so far it's working great.
#31
I've applied the patch in #25 to 6.x-1.11, and it works as described. I haven't encountered any problems yet. I think this is a very useful addition. Thanks.
#32
Is this patch likely to make it in to the module? If not, shouldn't it be prepared as a separate module? I like the functionality, but don't like applying patches that are not going to be adopted by the maintainers of the module, because it makes updating a pain. =(
#33
@greg.harvey - what we need is someone to really review the code. A review is not just "works for me" but is a review.
I'm inclined to apply this to the dev branches to let it get more tests/reviews there.
#34
@greggles - Fair enough. I won't be able to look at this as yet, but I've put a task of reviewing this patch in to our "Maintenance" backlog of work to do here. We could definitely do with this feature (specifically to use in conjunction with Pathauto for automated user profile aliases), but it's company policy not to apply patches that aren't going to be a part of a point release, so happy to help with the process if someone doesn't beat us to it. =)
Btw, it's not clear - should this be for D6? Version is set to D5, but latest patch seems to be for D6. I won't change it, as I could confuse things!
#35
@greg.harvey: patch in comment #24 is for version 5 and the one in #25 is for version 6.
#36
Could this work to give me profile fields as tokens in auto nodetitle module? It's weird, I applied the patch but no new tokens in replacement patterns of auto nodetitle. I thought those tokens in there came from token module?
#37
token_profile.inc referenced in this patch doesnt exist in the token 6 module...
#38
After installing the patch: (d5)
any ideas why the $mytext = token_replace($mytext,$type = 'user', $object = NULL, $leading = '[', $trailing = ']'); successfully replaces the [user] token, but returns empty if the token is [profile_name]??
I can see the new tokens from the profile module under the user object.
#39
I found a few problems with the D6 patch in #25 while trying to benchmark it.
First, there was a bug with profile date fields that was caused by unserializing the field after the profile module had already unserialized it. For url fields, the patch in #25 produces a token that has the text of the url, but no link. And for textarea fields, the newlines are stripped by check_plain, resulting in a single line textfield returned by the token.
The attached patch fixes these problems.
I repeated the benchmarking that deviantintegral described in #19 for this new patch using the latest dev code. I modified the process slightly, adding a total of 11 profile fields, 5 textfields and one of each of the other fields (date, url, textarea, checkbox, freeform list, and list selection). I then modified the code in #19 for D6 and extended it to randomly populate all of these profile fields for each of the 2000 users in the database. I used a similar testpage for the benchmark that does a token_replace on the 11 profile fields.
The benchmark results before and after the updated token_profile patch are attached. There is a slight increase in the request time (323 +/- 7.8 ms with the patch, compared to 307 +/- 9.3 ms without) that is just at the edge of being significant. Note that like deviantintegral, I could not see a difference in performance with token replace on 5 text profile fields. It took the more stressful test (probably the date field) to see a difference.
I still think this would be a very useful addition. It would be great if we could get this into the dev version. I am willing to do additional testing as needed.
#40
This patch worked flawlessly for me. I was able to get the core profile fields to show up in the replacement patterns for user path settings in pathauto which is a great help. Is there any chance this will be committed soon?
#41
The patch works like a charm, however, the profile fields are not available upon user registration, only on updating user profiel. I wanted to send out email with user details upon registration, but that does not work with this. Any ideas how to fix it?
#42
Tested the patch at #39 (D6) and found an issue, possibly the same issue as #41.
In my case, integration with Token and Mentions, the User Object didn't have the profile fields.
To fix the issue, you simply need to add the following line after line #30 of token_profile.inc:
profile_load_profile($account);Other than that, patch looks good and would be a great addition to Token.
Cheers,
Deciphered.
#43
+1 for this feature.
#44
I would be happy to re-roll another patch, but would like to know if the maintainers would be interested in committing this or not (once its marked RTBC, of course). If the maintainers don't intend to commit the code, there is no point in updating it.
I ask because the patch in #39 involves a small addition to token.module - though it completely parallels support for other core modules (like node, user, taxonomy and comment).
Some guidance would be appreciated.
#45
Now that token is in core for 7.x (and includes this feature) I don't think we should include this in 6.x.
If anything we should just backport the token code from 7.x to 6.x and provide this feature that way.
#46
6.x patch in #39 worked, but I needed the tokens to be available to Pathauto node titles. I created a custom module as so to solve the problem:
/**
* Implementation of hook_token_values().
*/
function mymodule_token_values($type, $object = NULL) {
$values = array();
if ($type == 'node') {
if (isset($object)) {
$account = $object;
}
else {
global $user;
$account = $user;
}
profile_load_profile($account);
$fields = _profile_token_profile_fields();
foreach ($fields as $name => $field) {
$field->value = $account->$name;
$values[$field->name] = _profile_token_format_field($field);
}
}
return $values;
}
/**
* Implementation of hook_token_list().
*/
function mymodule_token_list($type = 'all') {
if ($type == 'node') {
$fields = _profile_token_profile_fields();
foreach ($fields as $name => $field) {
$tokens['node'][$field->name] = $field->title;
}
return $tokens;
}
}
I am quite certain just adding "node" to the original patch would work as well, haven't tested this much yet but it appears to work great.
Thanks.
#47
Thanks everybody for sharing your features.
I took the patch from MGN in #39 and added the suggestion from Deciphered in #42 and included the node token support as suggested by JStarcher in #46.
I just edited the patch from #39, and didn't actually create a new one (because I don't know how to make the patch make a new file). I tested the patch and it works for me.
Changing the issue to version 6.x and to 'needs review'. I would also appreciate this functionality in the module, whether that be by commiting this patch or by backporting. What's the status on this?
Marcus
#48
Hi there,
I'm using drupal 6. After applying the patch mentioned above i got an "Array" when using the profile token with the invite module.
Can anyone help me to fix this problem?
Thanks in advance!