The Arcive of Official vBulletin Modifications Site.It is not a VB3 engine, just a parsed copy! |
|
[How-to] Decode custom user profile bitfield
This How to _should_ help someone setup custom profile fields that use multiple selections decode the bitfields for display (or other) purposes. If you see anything wrong with how I did this, please let me know, likewise if you have suggestions on how to improve it. I'm just putting this out there because no one else has, and I've had a few people ask about it. Let?s assume you are using Field7, and you have three settings you defined as multi-select checkbox (Yes, No, and Maybe). You can add more fields if you wish to test more. 1.Run a query to extract the data from the database for that profile field? These are all the settings for this field as defined in your custom profile field manager in the AdminCP. The following code will extract the settings you defined?in this case, ?Yes?, ?No?, and ?Maybe?. Code:
$custom_field_qry = $db->query_read("SELECT data from ". TABLE_PREFIX."profilefield where profilefieldid = '7' "); $custom_field_ary = $db->fetch_array($custom_field_qry); Code:
$my_custom_data = unserialize($custom_field_ary['data']); 3. Now we need to match the values from $my_custom_data to the values in $custom_user_data. The ?odd? thing here is we are matching binary data in custom_user_data, represented in a decimal number, to the real field in $my_custom_data, and set the values in $show[testbit] so we can display them in a template like forumhome. You may choose how you want to do this, of coarse (refer to the operator reference to understand how ?&? works at http://us2.php.net/manual/en/language.operators.php): Code:
foreach($my_custom_data AS $key => $val) { if ($vbulletin->userinfo[field7] & pow(2,$key)) { $show[testbit] .= $val." "; } } So for our example, edit the forumhome template, and add ?Testing: $show[testbit]? right below $navbar like shown below: Code:
$stylevar[htmldoctype] <html dir="$stylevar[textdirection]" lang="$stylevar[languagecode]"> <head> <!-- no cache headers --> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="-1" /> <meta http-equiv="Cache-Control" content="no-cache" /> <!-- end no cache headers --> $headinclude <title><phrase 1="$vboptions[bbtitle]">$vbphrase[x_powered_by_vbulletin]</phrase></title> </head> <body> $header $navbar Testing: $show[testbit] <!-- main --> Code:
$custom_field_qry = $db->query_read("SELECT data from ". TABLE_PREFIX."profilefield where profilefieldid = '7' "); $custom_field_ary = $db->fetch_array($custom_field_qry); $my_custom_data = unserialize($custom_field_ary['data']); foreach($my_custom_data AS $key => $val) { if ($vbulletin->userinfo[field7] & pow(2,$key)) { $show[testbit] .= $val." "; } } Now load up your UserCP, check mark whatever boxes you like, and then load up your main forumhome homepage. It should show you all the options you select (and only those options) delimited by a space. |
#2
|
||||
|
||||
Joel, that works really nicely for FORUMHOME, but I am trying to get it to work in the MEMBERINFO template and using hook location member_complete and it's returning my profile's data, not the member who's profile i am viewing...
Thanks! |
#3
|
|||
|
|||
Quote:
Code:
if ($vbulletin->userinfo[field7] & pow(2,$key)) What you need to do is query for that users profile fieldX values. In memberinfo, only hidden field aren't already decoded... So I'm not sure what you want to do exactly, but you could make sure they are not hidden and vB already will display the correct values for that user in their profile. If you really need this in member info, you could add a query using a plugin at member_customfields, something to this effect: Code:
$my_qry = $db->query_read("select userfield.field7 where " . TABLE_PREFIX ." userfield as userfield where userfield.userid = " . $userinfo['userid'].";" ); Code:
$my_profilefield_data = $db->fetch_array($my_qry); if ($my_profilefield_data[field7] & pow(2,$key)) { .... } Joel |
#4
|
||||
|
||||
It took me a couple hours to figure it out due to process of elimination and with your help above as well- but the following works for me:
Create a plugin using hook location member_complete with following code: Code:
$custom_field_qry = $db->query_read("SELECT data from ". TABLE_PREFIX."profilefield where profilefieldid = '26' "); $custom_field_ary = $db->fetch_array($custom_field_qry); $my_custom_data = unserialize($custom_field_ary['data']); foreach($my_custom_data AS $key => $val) { if ($userinfo[field26] & pow(2,$key)) { $show[testbit] .= $val.", "; } } BUT... It does however add 1 additional query to the page. I don't understand why it needs to run another query at all, since the correct serialized data is already in $userinfo[field26] to begin with, but it does now work at the least. I was attempting to unserialize the data and match it up without having to run the additional query above. I tried the following, but I am still a beginner with php and it wasn't working properly. Code:
$my_custom_data = unserialize($userinfo['field26']); foreach($my_custom_data AS $key => $val) { if ($userinfo[field26] & pow(2,$key)) { $show[testbit] .= $val.", "; } } |
#5
|
|||
|
|||
Some screenshot please?
|
#6
|
|||
|
|||
You have to run the query because field26 in the user info does not contain the actual data, just the bitfield data. All you get in the bitfield is 1's and 0's. Basically you have to match the real array with $userinfo[field26].
To visualize may be easier... imagine your array with "Yes", "No" and "Maybe" values (in that order in your custom field manager), which is contained NOT in userinfo[$field26] but in $my_custom_data as outlined above. $my_custom_data looks like this: $my_custom_data[0] = "Yes" $my_custom_data[1] = "No" $my_custom_data[2] = "Maybe" Now, $userinfo[field26] looks like this when "Yes" is set (in binary): 001 (or simply "1", but the leading zero's may help you visualize here) So when you compare the fields with " if ($userinfo[field26] & pow(2,$key)" you are essentially doing this: $my_custom_data[0] = "Yes" 1 (YES, user has it) $my_custom_data[1] = "No" 0 (No, User doesnt have it set) $my_custom_data[2] = "Maybe" 0 (No, User doesnt have it set) Now, imagine Yes and Maybe are set for this user. $userinfo[field26] will be set to "5" in decimal, and when converted to binary is "101"... ON, OFF, ON... so lets compare it to $my_custom_data: $my_custom_data[0] = "Yes" 1 (YES, user has it) $my_custom_data[1] = "No" 0 (No, User doesnt have it set) $my_custom_data[2] = "Maybe" 1 (YES, user has it) Likewise, the code you posted: Code:
$my_custom_data = unserialize($userinfo['field26']); foreach($my_custom_data AS $key => $val) { if ($userinfo[field26] & pow(2,$key)) { $show[testbit] .= $val.", "; } } In your case, around line 560 in member.php Code:
$customfields = ''; while ($profilefield = $db->fetch_array($profilefields)) { exec_switch_bg(); $profilefieldname = "field$profilefield[profilefieldid]"; if ($profilefield['type'] == 'checkbox' OR $profilefield['type'] == 'select_multiple') { $data = unserialize($profilefield['data']); foreach ($data AS $key => $val) { if ($userinfo["$profilefieldname"] & pow(2, $key)) { $profilefield['value'] .= iif($profilefield['value'], ', ') . $val; } } } Hope this helps. Joel Quote:
|
#7
|
||||
|
||||
that helps me understand the bitfields more, thanks Joel, you have been a tremendous help!
|
#8
|
|||
|
|||
Glad I could help.
Joel |
|
|
X vBulletin 3.8.12 by vBS Debug Information | |
---|---|
|
|
More Information | |
Template Usage:
Phrase Groups Available:
|
Included Files:
Hooks Called:
|