Is there a way to tell the user that they have logged out? The default behavior appears to take them to the homepage but doesn't actually display a message -- and I don't have anything on the homepage that visually indicates whether the user is logged in or not.

I've looked into hook_user about this, but no matter what I try, I can't seem to get drupal_set_message() working on logout.

I've found this post http://drupal.org/node/306268 that talks about crafting the destination URL on logout. So I could probably redirect the user to a custom page telling them that they've logged out. But ideally I would just take them back to the homepage and display a message at the top indicating that they've now logged out.

Any ideas?

Comments

gawas.sachin’s picture

having same problem.

anil614sagar’s picture

Hi,

You should use hook_user http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hoo... in your custom module with $op as logout.

Using above hook just write a drupal_set_message saying "you are logged out" inside case logout.

Hope you got the answer...

Cheers,
Anil Sagar,
Lead Drupal Developer,
Azri Soulutions,
http://azrisolutions.com/

gawas.sachin’s picture

I did same. But drupal_set_message doesn't work out on $op == 'logout'

but drupal_set_message does work on $op == 'login'.

May be drupal doesn't show messages to Anonymous User.

m4olivei’s picture

Looks like a known bug:

http://drupal.org/node/754560

anil614sagar’s picture

Hi,

We are talking about drupal 6.x

Cheers,
Anil Sagar,
Lead Drupal Developer,
Azri Soulutions,
http://azrisolutions.com/

wirka’s picture

Drupal 7, I hack the function of user_logout() on user.pages.inc:

function user_logout() {
  global $user;

  watchdog('user', 'Session closed for %name.', array('%name' => $user->name));

  module_invoke_all('user_logout', $user);

  // Destroy the current session, and reset $user to the anonymous user.
  session_destroy();

  drupal_goto();
} 

Change drupal_goto()become to drupal_goto('', array('query' => array('logout' => '1')));. And then I make below function on my theme function file.

function MYTHEME_preprocess_page($var){
	if($_GET['logout'] == '1'){
		drupal_set_message('You are loged out.', 'info');
	}
}

However look dirty but it make it done.

Jaypan’s picture

You don't need to hack core (in D7 at least, I didn't look at D6). You can use hook_user_logout(), and set your message there:

function my_module_user_logout()
{
  drupal_set_message(t('You are now logged out'));
}
le72’s picture

Not working!

Jaypan’s picture

Not wrong. Did you change 'my_module' to your module or theme name, and clear your cache? If so, then show us your code. Saying 'not working' with nothing else doesn't help us to help you.

le72’s picture

After performing all the hooks, drupal executes core function user_logout() which basically destroy all the session variables. So, the message never gets displayed.

Please read here https://api.drupal.org/api/drupal/modules!user!user.api.php/function/hoo...

wonder95’s picture

Actually, that's not true. If you look at the code that @wirka posted above, hook_drupal_logout() is called from within user_logout(), and right after that, session_destroy() is called, which destroys $_SESSION. Then, when drupal_get_message() is called on the next page load, there is nothing in $_SESSION to display.

le72’s picture

Jaypan's code is not working. Wirka's code hacks drupal core and, as author said it is dirty.

Jaypan’s picture

Yeah, looking through my code now, I can see how it won't work.

I don't see a way around this however. As the session is destroyed at the end of the logout, and the next session is not built until the begin of the fresh page load, there is no session nor any hook into which to either save the message, or store a reference to the logout in order to save the message.

jay.lee.bio’s picture

Here's the simplest solution I know of that at least works 100%: https://www.drupal.org/node/2345007

I also wrote a blog post on how to display the username (including the Real Name) in the logout message, such as "You are now logged out, @username."

But eventually I kept coming back here to dig deeper into more of the code, and was able to successfully turn it into a module. Thanks guys!

____________________

https://jay.lee.bio

rimu’s picture

Just before you call user_logout (or in hook_user_logout), set a cookie with the message you want to display

setcookie('my_message', t("Goodbye, have a nice evening!"), time() + (86400 * 30), "/");

... then in hook_init, display whatever is in the cookie and delete the cookie


function MYMODULE_init() {
  if(!empty($_COOKIE['my_message'])) {
    drupal_set_message($_COOKIE['my_message']);
    setcookie('my_message', '', time() - 3600);
  }
}
Jaypan’s picture

Nice solution. This could be set up in hook_user_logout().

TwoD’s picture

The easiest workaround is to simply do it like this:

module_load_include('inc', 'user', 'user.pages');
user_logout_current_user();
drupal_set_message('You have been logged out');
drupal_goto();

This does exactly the same thing as user_logout() and just sets the message after destroying the original session.
The message will still be stored in $_SESSION['messages'], but the user will no longer be authenticated.

Jaypan’s picture

Nice solution!

permanaj’s picture

Hi, in what hook should I put this code?

alesr’s picture

It's hard to do this without hacking core because there's no alter you can call after session_destroy().

A solution (where I could use the code above) is:

/**
 * Implements hook_menu().
 */
function YOURMODULE_menu() {
  $items = array();
  $items['user/log-out'] = array(
    'page callback' => 'YOURMODULE_user_logout_with_message',
    'access callback' => TRUE,
  );
  return $items;
}


/**
 * Custom User logout callback to use drupal_set_message() after session_destroy().
 */
function YOURMODULE_user_logout_with_message() {
  module_load_include('inc', 'user', 'user.pages');
  user_logout_current_user();
  drupal_set_message('You have been logged out');
  drupal_goto();
}

So instead of hacking core, you can change the link on your site pointing to "/user/log-out" (originally it is /user/logout) and it calls your custom user logout callback.

permanaj’s picture

This page is the first result on Google when I had problem about logout message, to help my future self I'll post here for Drupal 8.

Recreate the logout functionality. It's just calling user_logout() function.

For this, I create:

A method in SomeController

public function logout() {
  user_logout();
  return $this->redirect('<front>', [], ['query' => ['logout' => 1]]);
}

An event subcriber, subscribe to KernelEvents::REQUEST

$queryLogout = \Drupal::request()->query->get('logout');
if (!empty($queryLogout) && $queryLogout == 1) {
  drupal_set_message("You are logged out");
}

A router subcriber, altering user.logout route's controller

protected function alterRoutes(RouteCollection $collection) {

  // Change controller who handle logout.
  if ($routeLogout = $collection->get('user.logout')) {
    $routeLogout->setDefault('_controller', '\Drupal\my_module\Controller\SomeController::logout');
  }
}
msypes’s picture

Thanks for posting this solution @permanaj. This works very well.

A few alterations for anyone coming across this:

drupal_set_message() is now deprecated. Use \Drupal::messenger()->addStatus() or addMessage() instead.

Also, I found that if you log out and immediately back in, the above code displays the message again. To avoid that I modified the event subscriber's code thusly:

$queryLogout = \Drupal::request()->query->get('logout');
$referer = $request->headers->get('referer');

if (!empty($queryLogout) && $queryLogout == 1 && strpos($referer,'?logout=1') === false) {
  $messenger = \Drupal::messenger();
  $messenger->addStatus(t('You have successfully logged out of the system.'));
}

 

Michael

david.carmona’s picture

Was looking for that too! Just an advice, 

if (!empty($queryLogout) && $queryLogout == 1 && strpos($referer,'?logout=1') === false)

'false' needs to be FALSE to follow drupal coding standards. 

pmagunia’s picture

Thanks for this solution. I can get the logout message to show but it shows up one page too late (off by one error).

EDIT: Nevermind the solution works. My RouteSubscriber was off.

RAWDESK’s picture

The solution I was looking for !

paulmartin84’s picture

At first I thought this was impossible in D7 without hacking core, as the session is destroyed and then the user is almost instantly redirected to the homepage. However, drupal_goto has an alter hook, This is during the new session so stuff can be added back in, or copied across in a global.

The below shows an example, the first 2 hooks, are all that is needed to pass data into the new session including calling drupal set message if needed.

/**
 * Implements hook_user_logout
 */
function my_module_user_logout($account) {
  $GLOBALS['flag_user_logout'] = $account->uid;
}

/**
 * Implements hook_drupal_goto_alter
 */
function my_module_drupal_goto_alter(&$path, &$options, &$http_response_code) {
  if (isset($GLOBALS['flag_user_logout'])) {
    $_SESSION['old_user_id'] = $GLOBALS['flag_user_logout'];
  }
}

/**
 * Implements hook_preprocess_page
 */
function my_module_preprocess_page(&$vars) {
  if (isset($_SESSION['old_user_id'])) {
    drupal_add_js('alert("bye user ' . $_SESSION['old_user_id'] . '");', 'inline');
    unset($_SESSION['old_user_id']);
  }
}