Never Use the User Profile id Field to Get a User Profile

Don't make this disastrous error when getting a user's profile


This article is about a very insidious MODX error. It involves using the id field of the user profile to retrieve a user's profile. It will often work at first, but it can create an unholy mess over time.


The fact is that the id field of the user profile is completely arbitrary. It reflects the order in which the profile records were created and has no real relationship to the users whose profiles are stored there. The profile records are connected to their users by the profile's internalKey field. The internalKey field is guaranteed to hold the user ID of the user related to that profile.

Here's the confusing thing: because the users and their profiles are usually created at the same time, the profile's id field often matches the user ID of that profile's user. So if you try to get the current user's profile with this code, it will often work:

$profile = $modx->getObject('modUserProfile', $modx->user->get('id'));

Unfortunately, the two are almost certain to diverge over time as users and profiles are created and deleted. Eventually, you will get a user profile with this code, but it won't be the profile of the user you think it is. If you then modify the profile, you'll be modifying the profile of the wrong user without knowing it. After a while, you'll have a giant, unrepairable mess on your hands.


Some Solutions

Luckily, avoiding this problem is easy. You just need to get the user profile the right way.

If you have the user object (or want the profile of the current user), you can use the getOne() method:

/* If you have retrieved the user object yourself */
$profile = $user->getOne('Profile');

/* If you want the profile of the current logged-in user */
$profile = $modx->user->getOne('Profile');

Note the capital 'P' in 'Profile'. Profile is the xPDO alias for the modUserProfile object. Similarly, if you have the user profile and want to get the user object, you can do this:

$user = $profile->getOne('User');

What if you have the user's ID, but not the user object? You might, for example, be using the createdby, editedby, or publishedby field of the current resource. Those fields hold the user ID of the relevant user. Maybe you want to display the full name of the user who created the current resource. You could do this:

$id = $modx->resource->get('createdby');
$user = $modx->getObject('modUser', $id);
$profile = $user->getOne('Profile');
if ($profile) {
   return $profile->get('fullname');
}

But notice that in the code above, you don't really need the user object. It's wasteful to retrieve the user object when all you need is the profile. Remember that the internalKey field of the user profile always holds the correct user ID, so you can do this instead and make your snippet much more efficient:

$id = $modx->resource->get('createdby');
$profile = $modx->getObject('modUserProfile', array('internalKey' => $id));
if ($profile) {
    return $profile->get('fullname');
}

Final Notes

By now you should know never to use the id field of the user profile, but you might be wondering about the if ($profile) line in the code above. It's unlikely, but possible, for a user to have no user profile. Users created with "New User" in the Manager will always have a profile (though it may be empty except for the user's email address, which is required). Users created in code, though, can exist with no profile. They have a user ID, but there's no corresponding record in the user profile table. If you don't check to see if you got the profile before calling the profile's get() method, you risk having the site visitor experience a fatal, and fairly ugly, PHP error (or a blank screen) when get() is called on a non-object.

 

For more information on how to use MODX to create a web site, see my web site Bob's Guides, or better yet, buy my book: MODX: The Official Guide.

Looking for quality MODX Web Hosting? Look no further than Arvixe Web Hosting!



Comments (0)


Please login to comment.

  (Login)