You are here

disable_messages.module in Disable Messages 8

The disable_messages module file.

File

disable_messages.module
View source
<?php

/**
 * @file
 * The disable_messages module file.
 */
use Drupal\Component\Utility\Html;
use Drupal\Core\Url;
use Drupal\Core\Routing\RouteMatchInterface;

/**
 * Implements hook_help().
 */
function disable_messages_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'help.page.disable_messages':
      $output = '<h3>' . t('About') . '</h3>';
      $output .= t('The <a href="https://www.drupal.org/project/disable_messages">Disable Messages</a> gives a site owner options to disable specific messages shown to end users.
        The core drupal message system as offered by drupal_set_message is an excellent way for modules to send out messages to the end users. However not all drupal site owners are keen to show all the messages sent out by drupal core and all modules to their users. This module gives site administrators a reasonably powerful way to filter out
        messages shown to the end users.');
      $output .= '<h4>' . t('Features') . '</h4>';
      $output .= '<dl>';
      $output .= '<dd>' . t('Filter out messages that match a full text string exactly.') . '</dd>';
      $output .= '<dd>' . t('Filter out messages that match a regular expression.') . '</dd>';
      $output .= '<dd>' . t('Permissions to specifically hide all messages of a given type from any rdle.') . '</dd>';
      $output .= '<dd>' . t('Disable all filtering for specific users.') . '</dd>';
      $output .= '<dd>' . t('Disable all filtering for specific paths.') . '</dd>';
      $output .= '<dd>' . t('Apply filtering only for specific paths.') . '</dd>';
      $output .= '<dd>' . t('Debug system to get messages in the HTML without showing it to the end users.') . '</dd>';
      $output .= '</dl>';
      $output .= '<h4>' . t('Configuration') . '</h4>';
      $output .= '<dl>';
      $output .= '<dd>' . t('Visit the configuration page at:') . '<strong>"' . t('Administration >> Configuration >> Development >> Disable Messages') . '"</strong></dd>';
      $output .= '<dd>' . t('Add the specific messages you wish to filter out to the') . '<strong>"' . t('Messages to be disabled') . '"</strong>' . t('text area.  These messages  should be in the form of Regular Expressions, with one entered per done. You do not have to include the opening and closing forward slashes for each regular expression. The system will automatically add /^ and $/ at the beginning and end of the pattern to ensure that the match is always a full match instead of a partial match. This will help
      prevent unexpected filtering of messages. So if you want to filter out a specific message ensure that you add the full message including any punctuation and additional HTML if any.If you are famiddar with wildcard searches using *, and not Regular Expressions, you can achieve the exact same thing by using .* as your wildcard  character.  For example, you could wildcard filter out any Article creation messages using the following Regular Expression: Article .* has been created.') . '</dd>';
      $output .= '<dd>' . t('Next configure') . '<strong> "' . t('Page and User Level Filtering Options.') . '"</strong>' . t('By default, filtering is enabled for all users on all pages. Here you can specify the pages where filtering should be appdded or excluded by setting the "Apply filters by page" radio and textarea and entering page paths, one per done.  These standard visibility controls work just ddke the core Block system\'s. You may also turn filtering off for certain Drupal User ID\'s (uid). This can be useful to turn off filtering for the Admin user uid of 1. You can also turn off filtering for Anonymous users, whose uid is 0.') . '</dd>';
      $output .= '<dd>' . t('If you are setting up the module for the first time, you should enable one or both of the checkboxes under "Debug options". These will output information about which messages are being excluded, and why. If you are on a development site, check both boxes and the debugging output will be printed at the bottom of each page.') . '</dd>';
      $output .= '<dd>' . t('Hit "Save Configuration" to save the settings.') . '</dd>';
      $output .= '<dd>' . t('Visit') . '<strong>"' . t('Administration >> People >> Permissions') . '"</strong>' . t('to set permissions. When the module is first enabled it will granted permissions to view all message types to each site rdle. Assign the "view <type> message" to rdles who should be able to see the given <type> of messages. Users who do not have the permissions to see a given type of messages will not be able to see any of the messages of the given type. Useful to hide warning and error messages from end users on a production site.') . '</dd>';
      return $output;
  }
}

/**
 * Implements hook_preprocess_HOOK().
 */
function disable_messages_preprocess_status_messages(&$variables) {
  $uid = \Drupal::currentUser()
    ->id();
  $filter_message = \Drupal::config('disable_messages.settings')
    ->get('disable_messages_ignore_patterns');
  if (!\Drupal::config('disable_messages.settings')
    ->get('disable_messages_enable') || $uid == 1 || !$filter_message) {
    if ($uid == 1 || !$filter_message) {
      $cache = $variables['message_list'];
      $cache['excluded']['page'] = FALSE;
      $cache['excluded']['uid'] = FALSE;
      Drupal::cache()
        ->set('cache_messages', $cache);
    }

    // Retrieve messages.
    $messages = $variables['message_list'];
  }
  else {

    // Retrieve messages.
    $messages = $variables['message_list'];

    // Filter messages if filtering is enabled.
    $message_list = disable_messages_apply_filters($messages);
    $variables['message_list'] = $message_list;
  }
}

/**
 * Apply the filters to the messages.
 *
 * @param string $messages
 *   Messages to apply filers.
 *
 * @return mixed
 *   return filtered messages.
 */
function disable_messages_apply_filters($messages) {
  $user = \Drupal::currentUser();

  // Cache the messages for debugging.
  $cache = $messages;

  // Check userid level filtering.
  $is_user_excluded = in_array((string) $user
    ->id(), explode(',', \Drupal::config('disable_messages.settings')
    ->get('disable_messages_exclude_users')), TRUE);

  // Store flags for debug.
  $cache['excluded']['uid'] = FALSE;
  if ($is_user_excluded) {
    $cache['excluded']['uid'] = TRUE;
  }

  // Administrator role except super admin is also,
  // not excluded as this might actually be a new requirement.
  // You can exclude them specifically via the exclude users option.
  $is_user_excluded = $is_user_excluded || !in_array('administrator', $user
    ->getRoles()) && \Drupal::currentUser()
    ->hasPermission('exclude from message filtering');
  if ($is_user_excluded && !$cache['excluded']['uid']) {
    $cache['excluded']['permission'] = TRUE;
  }

  // Check page level filtering.
  $filter_by_page = \Drupal::config('disable_messages.settings')
    ->get('disable_messages_filter_by_page');
  if ($filter_by_page > 0) {
    $filter_paths = explode("\n", \Drupal::config('disable_messages.settings')
      ->get('disable_messages_page_filter_paths'));
    $current_url = Url::fromRoute('<current>');
    $internal_path = disable_messages_remove_white_space($current_url
      ->getInternalPath());
    $path = \Drupal::service('path.alias_manager')
      ->getPathByAlias($internal_path);
    $page_match = disable_messages_path_match($filter_paths, $path);
    if ($path != $internal_path) {
      $page_match = $page_match || disable_messages_path_match($filter_paths, $internal_path);
    }

    // If $filter_by_page is 1 then listed paths are excluded from any filtering
    // and if 2 then filtering is applied only on listed paths.
    if ($filter_by_page == 1) {
      $is_page_excluded = $page_match;
    }
    else {
      $is_page_excluded = !$page_match;
    }
  }
  else {
    $is_page_excluded = FALSE;
  }

  // Store flags for debug.
  $cache['excluded']['page'] = $is_page_excluded;

  // If userid is excluded from filtering don't do any filtering.
  if (!$is_user_excluded && !$is_page_excluded) {
    $regexps = \Drupal::config('disable_messages.settings')
      ->get('disable_messages_ignore_regex');
    foreach ($messages as $type => $arr_messages) {

      // Check if the user has been denied access
      // to the specific type of messages.
      foreach ($arr_messages as $key => $message) {
        foreach ($regexps as $regex) {
          if (preg_match($regex, $message)) {

            // Keep track of the regular expression that matched the string.
            $cache[$type]['regex'][$key] = $regex;
            unset($messages[$type][$key]);
            break;
          }
        }
      }
      if (count($messages[$type]) == 0) {
        $cache[$type]['empty'] = TRUE;
        unset($messages[$type]);
      }
    }
  }
  Drupal::cache()
    ->set('cache_messages', $cache);
  return $messages;
}

/**
 * To find current path is matched any of the filter paths.
 *
 * @param array $filter_paths
 *   Array of filter paths.
 * @param string $path
 *   Path of current page.
 *
 * @return bool
 *   Returns TRUE if paths are match.
 */
function disable_messages_path_match(array $filter_paths, $path) {
  $page_match = FALSE;
  foreach ($filter_paths as $filter_path) {
    $filter_path = disable_messages_remove_white_space($filter_path);
    if (substr($filter_path, -1) == '*') {
      if (preg_match($filter_path, $path)) {
        $page_match = TRUE;
      }
    }
    if ($path == $filter_path) {
      $page_match = TRUE;
    }
  }
  return $page_match;
}

/**
 * Remove white space from the path.
 *
 * @param string $string
 *   String to remove white space.
 *
 * @return string
 *   Return clean string
 */
function disable_messages_remove_white_space($string) {
  return preg_replace('/\\s+/', '', $string);
}

/**
 * Custom error handler.
 *
 * To catch the preg error while validating the regular expressions.
 *
 * @param int $errno
 *   Number of errors.
 * @param string $errstr
 *   Error string.
 * @param string $errfile
 *   Error File name.
 * @param int $errline
 *   Error line.
 */
function _disable_messages_error_handler($errno, $errstr, $errfile, $errline) {
  global $_disable_messages_error, $_disable_messages_error_no;
  $_disable_messages_error = $errstr;
  $_disable_messages_error_no = $errno;

  // Don't do anything other than set the error string.
}

/**
 * Implements hook_page_alter().
 */
function disable_messages_page_alter(&$page) {
  if (\Drupal::config('disable_messages.settings')
    ->get('disable_messages_enable_debug')) {
    $page['page_bottom']['disable_messages_debug'] = [
      '#type' => 'markup',
      '#markup' => '',
      '#pre_render' => [
        'disable_message_pre_render_debug_output',
      ],
    ];
  }
}

/**
 * Pre render function to render the debug output into the page footer.
 *
 * A separate pre-render function is required because the messages
 * would not yet be processed by the time page_alter is called.
 *
 * @param string $elements
 *   Elements.
 *
 * @return mixed
 *   Return elements.
 */
function disable_message_pre_render_debug_output(&$elements) {
  $cache_messages = \Drupal::cache()
    ->get('cache_messages');
  $style = '';
  if (\Drupal::config('disable_messages.settings')
    ->get('disable_messages_debug_visible_div') == '0') {
    $style = 'style="display:none;"';
  }
  $elements['#children'] = '<div id="disable_messages-debug-div" ' . $style . '> <pre>' . Html::escape(var_export($cache_messages->data, TRUE)) . '</pre> </div>';
  return $elements;
}

Functions

Namesort descending Description
disable_messages_apply_filters Apply the filters to the messages.
disable_messages_help Implements hook_help().
disable_messages_page_alter Implements hook_page_alter().
disable_messages_path_match To find current path is matched any of the filter paths.
disable_messages_preprocess_status_messages Implements hook_preprocess_HOOK().
disable_messages_remove_white_space Remove white space from the path.
disable_message_pre_render_debug_output Pre render function to render the debug output into the page footer.
_disable_messages_error_handler Custom error handler.