In one of our recent projects, the client wanted to block users from changing some of their own profile values based on some run-time logic. However, even if nothing was changed, the user core module would send the message "The changes have been saved." which would be confusing for the user.
The accepted answer here will delete ALL pending Drupal messages if a match is found for one of the messages--perhaps not a desired outcome.
We decided to implement a more general-case message interception scheme. Given the restrictions not to upset the Drupal 7 core, it ends up being somewhat convoluted, but the run-time performance hit is mitigated given the extra conditionals.
Given that this code is accessing only the $_SESSION variable, it can be placed in a template or module, and the '...clear...' function should be called from within a late-stage preprocess-page hook/theme/template function (e.g., template_preprocess_page(), hook_page_build(), etc.).
Anyway, here's the code we used, in case it helps others:
/**
* Adds message to intercept and delete upon next page load.
*
* intercepts system message so that it's not displayed to users
* (usually to avoid confusing Drupal messages)
*
* @param string $message
* The exact text that will be intercepted.
*
* @param string $type
* The Drupal message type that will be intercepted.
*/
function mymodule_intercept_system_message($message = NULL, $type = 'status') {
if (NULL !== $message) {
$_SESSION['mymodule_intercepted_message'][$type][] = $message;
}
}
/**
* Clears system messages that have been flagged for interception.
*
* See: mymodule_intercept_system_message()
* Admin will still see the intercepted message with added prefix.
*
* @param bool $clear_flagged_messages
* boolean: true = All flagged messages are cleared for next page load, defaults
* to true
*
* @return
* bool TRUE if message was intercepted, FALSE otherwise
*/
function _mymodule_clear_intercepted_system_messages($clear_flagged_messages = true) {
/**
* Interact directly with $_SESSION since drupal core function drupal_get_messages()
* only allows for all or no messages to be deleted, not specific messages
*
* drupal messages:
* $_SESSION['messages'][type][idx] = message-text
* intercept messages:
* $_SESSION['mymodule_intercepted_message'][type][idx] = message-text;
*/
$retval = false;
if (isset($_SESSION['messages'])) {
if (isset($_SESSION['mymodule_intercepted_message'])) {
foreach ($_SESSION['messages'] as $type => $message_array) {
foreach ($message_array as $key => $message) {
if (isset($_SESSION['mymodule_intercepted_message'][$type])) {
foreach ($_SESSION['mymodule_intercepted_message'][$type] as $int_key => $int_message) {
if ($int_message === $message) {
//message found, clear it so it doesn't display
unset($_SESSION['messages'][$type][$key]);
//unset entire type if empty, so Drupal doesn't ouput blank message block
if (0 == count($_SESSION['messages'][$type])) {
unset($_SESSION['messages'][$type]);
// unset messages if empty,
// because Drupal core expects array not to exist if empty
if (0 == count($_SESSION['messages'])) {
unset($_SESSION['messages']);
}
}
$retval = true;
if (user_access('administer users')) {
//let admin know of message
drupal_set_message('Intercepted message was: ' . $message, $type);
}
}
}
}
}
}
}
}
if ($clear_flagged_messages) {
//clear out all flagged messages for next page load
unset($_SESSION['mymodule_intercepted_message']);
}
return $retval;
}