We recently completed a project which required a feature that there was no current Drupal module for. The closest around was admin_message, but wasn’t fully what I needed to do.
The feature is really simple. The client wanted a way to immediately show an alert on the page when they had something critical to announce. Think of Breaking News on CNN, the yellow banner that appears at the top. It shows above the content, everyone sees it, and you can X it out if you like. When you X it out, it fades away nicely, thanks to the excellent jQuery library.
Implementing it was actually really simple. I am in the process of cleaning up the code and submitting it to drupal.org. The hardest part to get around was controlling when to display the message to the user, and if they had closed it before. Don’t want someone seeing the same message multiple times with a closing button that doesn’t work, after all.
In order to do that, I would need to ‘remember’ the user for as long as I could. The first thing that came to mind was utilizing $_SESSION and/or the Drupal user object. I quickly found out that Drupal does not store any data about anonymous users, does not retain a cookie or save session data on them. This presented a problem in actually tracking a visitor.
I would need to use a cookie. However, it appears that Drupal has no wrapper/functions to make use of a cookie beyond the scope of the user object, which I needed in this case. I was able to get a few nudges in the right direction from fellow developers and came up with a solution that worked for me.
When a person comes to the site, we need to create a cookie and immediately set it. When cookies are set, they are not available until the next request, and we need to sidestep that as well. In the cookie, we are going to generate a Unique User ID (UUID) and store it. As long as cookies are enabled, the feature will work. True, you could use the IP to track someone, but if they are visiting from a company network or office, it is not too reliable.
The solution is pretty straightforward:
function mymodule_init() {
if (!isset($_COOKIE['UUID'])) {
$uuid = mymodule_get_uuid();
setcookie('UUID', $uuid, time() + 31536000, '/');
if (request_uri() == '/') {
drupal_goto('index.htm');
} else {
drupal_goto(request_uri());
}
}
}
So, when the hook_init() function is invoked by Drupal, our code is included. It checks for UUID in the cookie, and if it doesn’t exist, we generate a UUID (using another function), then call setcookie() to create our cookie value. Then, we immediately redirect the user to their page request using drupal_goto(). The first line redirects the user to the homepage if that was their initial request, without that, they are sent to http://www.yoursite.com// with an extra slash on the end. Cosmetic (and webstat) fix, you don’t have to do that if you don’t want to. drupal_goto() happens so fast the user does not realize anything happened, and our cookie is available right away.
It’s also important to note the ‘/’ in the setcookie(). This is an optional argument denoting the path of the cookie, but I could not get setcookie() to work in Drupal without it. Also, make sure your session and/or cookie lifetime is not set to 0 in settings.php. Your mileage may vary.
So now we have a UUID for the user. When they click on an alert to close it, an AJAX function fires, and their UUID is written to the database to indicate the UUID, node ID that performed a close action. This is a very useful solution when you want to track a user who may not be logged in (and may never log in).
For more information regarding cookies in Drupal, check out these links. Most of them are discussions I started to help me find an answer.
http://stackoverflow.com/questions/3397735/hook-user-op-load-does-not- fire
http://stackoverflow.com/questions/3197742/cnn-style-alert-in-drupal