We can access a few variables from anywhere at anytime in Drupal, and the most important of these variables is $user. The object $user contains (almost) everything you’ll ever need to know about the user that is currently surfing the web site. This user may be logged in (a logged in registered user, hence), or he may be an anonymous user (not quite so anonymous because we can fetch his IP address, from the variable $user).
Whenever we want to access the global-scope $user variable for any purpose, we need to specify the variable’s scope, so we always need at least 2 lines of code to fetch information about the “user” :
// we are to access the content of the global-scope variable $user global $user; // salutation to the user print 'Hello, ' . $user->name;
For the sake of simplicity, we’re now printing words, like Hello how dow you do, without concern for the fact that they won’t be translatable to other languages. To make any text we print translatable, we use Drupal’s function t() — t as in translatable text, not t as in text. In both Drupal 5.x and Drupal 6.x, the placeholder in the t() function (used for dynamic content) is !variable for input that you generated, programmatically or otherwise (like a number, a 'role' name). Also use the !variable placeholder to print an e-mail address. Use the placeholder @variable for user input — anything you want Drupal to sanitize for you.
Using the function t(), the last code snippet becomes :
global $user; // salutation to the “user” print t('Hello, @user.', array('@user' => $user->name));
If we’re curious about the content of this variable, that is, if we want to answer the question what is there to learn from $user, we can use this call, which will print the entire content of the variable in a green box on our web page :
drupal_set_message('<pre>' . print_r($user, TRUE) . ' </pre>');
If we don’t set the second argument of the php function print_r
to TRUE, the content will be displayed above the web page’s header. You might actually prefer that.
The only information not provided by the omniscient $user is whatever user profile “info” was added through customizable fields created by the admin, using the Profile module, these fields that were labelled by the admin profile_{something}
. We’ll see how to access this information in a bit. We’ll also discover how to answer the question : do I have the right to {do-this} ? where do-this is one of the actions listed on the Permissions page. But first thing first, what does $user provide ? The user unique id, to begin with.
print $user->uid;
The user unique id is 0 for an anonymous visitor, 1 for the Administrator, and a value higher than 1 for a logged in visitor, it really is a unique value for each of the web’s site members (a.k.a users).
print $user->name; print $user->mail;
In the last bit, the property mail
provides the e-mail address of the logged in visitor.
Now this :
if(isset($user->signature)) { print $user->signature; }
The signature
of the user is specified in his/her profile, it may or may not be shown at the bottom of his comments depending on your default theme, and “admin” settings. Also, it may not have been set at all by the user.
print t('You registered !time ago.', array('!time' => format_interval(time() - $user->created)));
The last bit prints how long ago the user registered. Now, when was the last time the user accessed the web site ? The property login
gives us that information.
print t('Last time you logged in was !time ago.', array('!time' => format_interval(time() - $user->login)));
We might want to get an actual date on these things.
print t('You registered on !date.', array('!date' => format_date($user->created, 'small')));
You don’t like how the small
, medium
and long
dates are formatted in Drupal (always including the time in the day) ? Use a custom PHP format :
print t('You registered on !date.', array('!date' => format_date($user->created, 'custom', 'l, j M Y')));
The property hostname
gives us the user’s I.P. addy.
print t('Your IP address is !IP.', array('!IP' => $user->hostname));
We can show the user’s picture.The property $user->picture gives us the path to the user’s picture’s file, so we can display his/her picture on the page, like so:
if (isset($user->picture)) { $alt = $title = t('@name’s picture', array('@name' => $user->name)); print theme('image', $user->picture, $alt, $title); }
But we should never do it like that. Why? The path given to the user picture is the actual path. If you're using private download, your user image was uploaded to a private folder, probably not in your web site root. Hence, you need Drupal to get the image for you. Typing the actual path as 'src' attribute for the image won't work. The image will be broken. Unless of course the folder is IN your web site root. Say it is. Now, you've just revealed in your HTML markup where your not-so-private upload folder is. Bad idea.
It is preferable to use the Drupal function theme_user_picture() for the same purpose. It comes with a free gift as well. The user photo will be clickable. It will link to the user’s profile page. Depending on your website settings, visitors may not have access to the members' profile, so the picture may not be clickable for them.
if (isset($user->picture)) { print theme('user_picture', $user); }
Here is your face.
You are not logged in. So you cannot see yourself.
No one will be able to see your face here, but _you_ will. This posting is excecuting PHP code. That code fetches information from the global-scope variable $user, and that $user is yourself. When I view this post, I see my face.
Is there something else we can get from $user ? Certainly!
We can check which roles (possibly plural) the user has :
if (in_array('authenticated user', $user->roles)) { print t('You are an authenticated user.'); }
There is another way to check if a user has a specific role. The $user->roles
property is an array of strings, and when a certain indexed key is set, the user has the role associated with that indexed key. Authenticated user goes with index 2, and Anonymous user goes with index 1.
if (isset($user->roles[2])) { print t('You are an authenticated user.'); } if (isset($user->roles[1])) { print t('You are an anonymous user.'); }
If we want to know if the user has the right to, say, 'view uploaded files', then we check for this condition, from anywhere (not only from the module that defines such permission) :
if (user_access('view uploaded files')) { print t('You have the right to download files attachments.'); }
Drupal’s function user_access
informs us about the current user’s privileges, and it returns a boolean. If we want to know about another user’s privileges, we have to supply the function with a second argument. We will talk more about this in the next article.
If we want to fetch some user profile information, we first have to know the name of the profile field, that we added as an Administrator. That name begins with profile_
. If, for example, the profile field name was profile_about
, we would query the database like so :
SELECT column
FROM table1
JOIN table2
ON table1.foreign_key = table2.primary_key
WHERE table1.value = x AND WHERE table2.value = y
$result = db_query("SELECT pv.value FROM {profile_values} pv JOIN {profile_fields} pf ON pf.fid = pv.fid WHERE pv.uid = %d AND pf.name = '%s'", $user->uid, "profile_about"); if($about = db_fetch_object($result)) { print '<p>' . t('About @name : @value.', array( '@name' => $user->name, '@value' => $about->value, ) . '</p>'; }
Comments
Best read Handle text in a
Best read Handle text in a secure fashion to improve upon the code samples.
Thanks. Very helpful info :)
Thanks. Very helpful info :)
Great link
Thank you, that's a very good link, Anonymous. I will work on improving the sample code, using the function t(), t as in translatable, and will make other improvements as well. :)
Thanks
Also.... learned something new today... I am just starting to get up to speed on drupal... and browsing your site to get a feel for what is possible....
You are welcome, Kate
:)
using t()
t() should not be used with string concatenation. For grammatical reasons, t() should envelope the whole sentence, with placeholders to indicate the varying parts. There are several very good reasons for that, one being that language grammar may dictate different order of the words and the varying parts. There are more grammatical reasons (e.g. context may influence word translation), and there are also practical reasons.
This:
is bad, because the translated 'ago' may have to proceed the time interval.
The correct way to do it:
echo t('last time you logged was @time ago', array('@time' => format_interval(...));
And
t('Hello, '). $name
should be writtent('Hello, @name', array('@name' => $name))
. This also gives the translator more freedom: he could translate that string to '@name, nice to see you again' or 'Hello, @name!!!' (yes, the target language may remain English -- designers, not just translators, are also among the 'clients' of t()...).A word in English may translate into different words in the target language, depending on the context. Thus doing the following is bad:
$a = t('word1') . $var . t(': word2') . t('word3');
$b = t('word1') . t('word3') . t('word6');
And there's also a practical reason why it's bad: the translator won't understand what the hell ': word2' means.
Ahh! I could spank you for this!!!!!
Let's sum up this discussion:
It's really simple, you don't have to be a linguist, there's only one rule: wrap the whole sentence with t().
Oh, there's another rule:
Do
'
instead of'. t('blah blah') .'
'
t('
.blah blah
')
For the sake of simplicity,
For the sake of simplicity, we’re now printing words, like Hello how dow you do, without concern for the fact that they won’t be translatable to e-papierosy other languages. To make any text we print translatable, we use Drupal’s function t() — t as in translatable text, not t as in text. e-papierosy In both Drupal 5.x and Drupal 6.x, the placeholder in the t() function (used for dynamic content) is !variable e-papierosy for input that you generated, programmatically or otherwise (like a number, a 'role' name). Also use the !variable placeholder to print an e-mail address. Use the placeholder @variable for user input — anything you want Drupal to sanitize for you.
elektroniczne papierosy
Yes, please spank me for this
I forgot that t() could take "placeholders", Mooffie. Please visit my web site more often. That way I won't make a fool of myself ;) I could spank you too, you know.
No need to be a linguist, no : I speak French (all the time) and it's plain to see that my code is untranslatable to French. :) Gotta love you. I missed you.
I will redo all the book now.
Thanks, Mooffie.
Hi
A most interesting site you have. I browsed it earlier today, as a guest. I like it. Plenty of reasons to spank me, I'm afraid ;-)
Some random comments:
I didn't know that. You're right.
It has a second, optional, parameter.
I believe
$user->roles
has only numeric keys.The DB is a "black box" for us, we "don't know" what is the SQL for loading profiles. Besides, your query only loads profile.module fileds, and other modules may add other fields. We should simply:
$account = user_load(array('uid' => $uid));
echo $account->profile_about;
Yes. That's the whole point of naming the parameters (%bla) instead of using sprintf-like syntax (%s). BTW, it's PHP's strtr() that does the search/replace.
Hi again (and thanks for the beautiful compliments)
I tried this, and it doesn't work (I tested this in Drupal 5 only). Either from a node's content, from a block, or from a module. But it apparently works on user pages, according to the Drupal handbooks. Go figure.
Thanks for telling me about user_access. Indeed, it takes an account as optional second parameter (I will need to change what I wrote) :
I tested this too (in Drupal 5). It works. But now I am second-guessing myself. I will have to test it again. Just to be sure, sure, sure. That's quite important.
...
Heh? It ought to work.
And thanks for telling me profile fields are not pre-loaded (I re-edited my comment, but, noting the timestamp on your comment, you probably hadn't noticed my update).
Tested it (D5). Doesn't work. On my system $roles has only numeric keys. Maybe you've installed a module whose by-product is this modification of $user->roles to include string keys.
But why would you need such code? I'm not sure I envision a need to determine whether a user belongs to some particular role. I only see a need to determine whether a user has some particular permission. (hmmm..... is it "whether" or "wether"? ;-)
Not long ago websites had code that didn't work on Mozilla. Not because mozilla wasn't capable, but because the websites did
"if browser == explorer then do something"
instead of"if browser.feature == true then do something"
. One should check permissions, not roles.And thanks for telling me
I noticed your edit after my submit :)
Mooffie, my 'profile_about' is a custom (admin-created) profile field.
You are correct. I wanted to make it exhaustive. I do think that it can be useful sometimes (some people ask on the forum how to check for this, but not often).
user_load()
After a call to user_load(), I still cannot use $user->profile_{some_field} in Drupal 4.7. I just tested it again. I have to get it through a database query. I checked from a homemade module, inside the {my module}_nodeapi hook function. Maybe it's a question of timing.
It's whether
Using feature-sensing rather than role-sniffing. :)
I really like your analogy.
Handling Date Profile Fields
Hi there,
I have a specific use for the returning of the user profile function you have included in the above article, but I need to do this with the data from a date field.
I get the following output when I use the method mentioned above:
a:3:{s:5:"month";s:1:"3";s:3:"day";s:2:"30";s:4:"year";s:4:"2008";}
I can see the date I need in there, but I am not sure how to format it in the standard date format (any format would be nice).
eg. 6 April 2007, or, 06/04/2007
I am not sure if this can be done, but I would appreciate any insight you could offer to my situation.
Thank,
Nathan
drupal_unpack with JSON
Use the function drupal_unpack. It will take the user 'data' field (which is in JSON notation I believe) and convert it into a multidimensional array and append that array to the object. Examine what you get with that. Let me know how you solve your problem, please.
<?php
$result = db_query('SELECT * FROM {users} u WHERE u.uid = %d', $uid);
$user = db_fetch_object($result);
$user = drupal_unpack($user);
drupal_set_message('' . print_r($user, TRUE) . '');
// or just : echo '' . print_r($user, TRUE) . '';
?>
While I put this together, I
While I put this together, I did not write all of it, having used many snippets and bits of code from the drupal.org community.
<?php
global $user;
$user = user_load(array('uid'=>$user->uid));
# print date
$converted_date = convert_profile_date($user->profile_date);
echo 'Support expiry: ' . date('l, j M Y', $converted_date);
function convert_profile_date($profile_date_ar) {
# takes a profile date array and converts it to a date variable.
$output = mktime(0, 0, 0, $profile_date_ar['month'], $profile_date_ar['day'], $profile_date_ar['year']);
return $output; }
?>
That will output the date using the php date() function, so you can put it into any format you wish.
The above converts the date array from the profile_date field and displays the following:
Saturday, 9 Feb 2008
I am sure there are better ways to do it, but that is the only one I have worked out so far.
Good job
I want to say thank you. I'm new to working with drupal and was searching for information on customizing content for authenticated users and this helped out a lot. Thanks again, this make working with user information easy to understand.
I must speak to you by such
I must speak to you by such means as are within my reach. You pierce my soul. I am half agony, half hope. Tell me not that I am too late, that such precious feelings are gone for ever. I offer myself to you again with a heart even more your own than when you almost broke it, eight years and a half ago. Dare not say that man forgets sooner than woman, that his love has an earlier death.
Share It
Maybe I can use this svelte
Maybe I can use this svelte my noesis marketing and Ive been use whatsoever ethnical media in try a interaction and they eff handiwork a big friendliness on me.