You are here

private function HeartbeatMessageBuilder::checkAccess in Heartbeat 6.4

Function to check access on messages This behaviour is set by a heartbeat message configuration to overrule the chosen display access type

1 call to HeartbeatMessageBuilder::checkAccess()
HeartbeatMessageBuilder::execute in includes/heartbeatmessagebuilder.inc
Executes a query, putting the result into a wellformed stream of heartbeat activity objects

File

includes/heartbeatmessagebuilder.inc, line 138
Strategy with access behaviour

Class

HeartbeatMessageBuilder
Class HeartbeatMessageBuilder Message builder that fetches and customizes users activity on the site. The builder takes a heartbeataccess object to handle the request to fetch the messages.

Code

private function checkAccess(HeartbeatParser $heartbeat) {
  global $user;
  $stream = $this->_heartbeatState
    ->getStream();
  $tags = $heartbeat
    ->get_tags();

  // First check access on message perms, roles and node access.
  foreach ($heartbeat->raw_messages as $key => $message) {

    // Check on xss attack before other modules can change messages.
    $heartbeat->raw_messages[$key]->message = filter_xss($heartbeat->raw_messages[$key]->message, $tags);
    $heartbeat->raw_messages[$key]->message_concat = filter_xss($heartbeat->raw_messages[$key]->message_concat, $tags);

    // Rewrite message access if the access was not changed at log-time
    // and if the user has configured the access state of this message type.
    $message->access = $message->template->perms;
    if (isset($message->actor->heartbeat_activity_settings[$message->message_id]['access'])) {
      $message->access = $message->actor->heartbeat_activity_settings[$message->message_id]['access'];
    }

    // Remove messages that are excluded for everyone
    if ($message->access == HEARTBEAT_NONE) {
      unset($heartbeat->raw_messages[$key]);
      $this
        ->addError('Activity message #' . $message->uaid . ' is filtered from display, because it was excluded for everyone.');
      continue;
    }

    // Remove messages set private by site administrator
    // and remove messages set private by user profile setting.
    $private = $message->template->perms === HEARTBEAT_PRIVATE || (int) $message->access === HEARTBEAT_PRIVATE;
    if ($private && $user->uid != $message->actor->uid) {
      unset($heartbeat->raw_messages[$key]);
      $this
        ->addError('Activity message #' . $message->uaid . ' is filtered from display, because it was blocked by administrator or the owner of the message.');
      continue;
    }

    // Check the possibility for the active user to be skipped out.
    if ($message->actor->uid == $this->_heartbeatState
      ->getActiveUser()) {
      if ($this->_heartbeatState
        ->skipActiveUser()) {
        unset($heartbeat->raw_messages[$key]);
        $this
          ->addError('Activity message #' . $message->uaid . '(' . $message->message_id . ') is filtered from display, because the activity owner [' . $message->actor->name . '] is the displayed user [' . $this->_heartbeatState
          ->getActiveUser() . '] which is skipped in this context.');
      }
    }

    // Remove messages that non-related users don't have access for.
    // Some different handling is needed for the displayed user watching his own.
    if ($message->uid && $user->uid != $message->actor->uid && ($message->access == HEARTBEAT_PUBLIC_TO_CONNECTED || $message->template->perms == HEARTBEAT_PUBLIC_TO_CONNECTED)) {

      // Only check the relations for the users if it's needed.
      $heartbeat_relations = heartbeat_get_related_uids($user->uid);

      // Check if the logged-in user is connected to the actor of the activity.
      if (!isset($heartbeat_relations[$message->actor->uid])) {
        unset($heartbeat->raw_messages[$key]);
        $this
          ->addError('Activity message #' . $message->uaid . '(' . $message->message_id . ') is filtered from display, because the activity owner [' . $message->actor->name . '] is not connected to displayed user ' . $user->name . '[' . $user->uid . '].');
        continue;
      }
      $heartbeat->raw_messages[$key]->actor->heartbeat_relations = $heartbeat_relations;
    }

    // Remove messages that are restricted to roles.
    if (isset($message->template->roles) && !isset($message->template->roles[DRUPAL_ANONYMOUS_RID])) {
      $access = FALSE;
      foreach ($message->template->roles as $rid) {
        if (isset($user->roles[$rid])) {
          $access = TRUE;
          break;
        }
      }
      if (!$access) {
        unset($heartbeat->raw_messages[$key]);
        $this
          ->addError('Activity message #' . $message->uaid . ' is filtered from display, because this message is blocked by role.');
        continue;
      }
    }

    // Check if the current user has access to nodes and user profiles,
    // but only if the administrator did not overrule this setting
    if (variable_get('heartbeat_context_perm', 0) == 0) {
      if (!user_access('access user activity')) {
        $heartbeat->raw_messages[$key]->uid_access = FALSE;
        $this
          ->addError('Activity message #' . $message->uaid . ' is filtered from display, because this message is blocked by profile access.');
      }

      // if user can't access profiles, change the link for the user name only.
      if (!user_access('access user profiles')) {
        $heartbeat->raw_messages[$key]->message = str_replace($heartbeat->raw_messages[$key]->variables['@username'], $heartbeat->raw_messages[$key]->actor->name, $heartbeat->raw_messages[$key]->message);
      }
      $this
        ->checkNodeAccess($heartbeat->raw_messages[$key], $user);
    }
  }

  // Check if any filters are active giving other modules the chance
  // to list the messages that are evaluated by this filter
  if (isset($_GET['filters'])) {
    $active_filters = drupal_map_assoc(explode(',', $_GET['filters']));
    $filtered_messages = array();
    foreach ($active_filters as $filter) {
      $function = 'heartbeat_filter_' . str_replace('-', '_', $filter);
      if (function_exists($function)) {
        $filtered_messages += $function($heartbeat->raw_messages, $this->_heartbeatState);
      }
    }
    $heartbeat->raw_messages = $filtered_messages;
  }

  // This hook is invoked BEFORE calculating the maximum
  // number of messages to show,
  // giving other modules the opportunity to remove messages
  // based on their own parameters and custom reasons.
  $hook = 'heartbeat_messages_alter';
  foreach (module_implements($hook) as $module) {
    $function = $module . '_' . $hook;
    $result = $function($heartbeat->raw_messages, $this->_heartbeatState);
  }

  // The difficulty remains in having the possibility to leave the
  // user with no site activity at display. Any propositions?
  // In short: problem when querying to few messages, having lots
  // of them denied and leaving the user with no messages left.
}