You are here

heartbeat.module in Heartbeat 8

Contains heartbeat.module.

File

heartbeat.module
View source
<?php

/**
 * @file
 * Contains heartbeat.module.
 */
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Url;
use Drupal\Core\Form\FormState;
use Drupal\node\NodeInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Entity;
use Drupal\Component\Utility\Html;
use Drupal\Core\Database\Database;
use Drupal\heartbeat\Entity\FILE_FIELD;
use Drupal\heartbeat\Entity\Heartbeat;
use GuzzleHttp\Exception\RequestException;
use Drupal\heartbeat\Entity\HeartbeatType;
use Drupal\heartbeat\Ajax\UpdateFeedCommand;

/**
 * Implements hook_help().
 */
function heartbeat_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {

    // Main module help for the heartbeat module.
    case 'help.page.heartbeat':
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('Heartbeat for Drupal 8') . '</p>';
      return $output;
    default:
  }
}

/**
 * Implements hook_theme().
 */
function heartbeat_theme() {
  $theme = [];
  $theme['heartbeat'] = array(
    'render element' => 'elements',
    'file' => 'heartbeat.page.inc',
    'template' => 'heartbeat',
  );
  $theme['heartbeat_content_add_list'] = [
    'render element' => 'content',
    'variables' => [
      'content' => NULL,
    ],
    'file' => 'heartbeat.page.inc',
  ];
  $theme['heartbeat_stream'] = [
    'variables' => array(
      'messages' => NULL,
      'zilla' => 2,
    ),
  ];
  $theme['friend_interaction'] = [
    'variables' => array(
      'user' => NULL,
      'flag' => NULL,
      'userPic' => NULL,
      'testing' => 'testing yo',
    ),
  ];
  return $theme;
}

/**
 * Implements hook_theme_suggestions_HOOK().
 */
function heartbeat_theme_suggestions_heartbeat(array $variables) {
  $suggestions = array();
  $entity = $variables['elements']['#heartbeat'];
  $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');
  $suggestions[] = 'heartbeat__' . $sanitized_view_mode;
  $suggestions[] = 'heartbeat__' . $entity
    ->bundle();
  $suggestions[] = 'heartbeat__' . $entity
    ->bundle() . '__' . $sanitized_view_mode;
  $suggestions[] = 'heartbeat__' . $entity
    ->id();
  $suggestions[] = 'heartbeat__' . $entity
    ->id() . '__' . $sanitized_view_mode;
  return $suggestions;
}

/**
 * Implements hook_entity_insert().
 */
function heartbeat_entity_insert(EntityInterface $entity) {
  $bundleSaved = false;
  switch (true) {
    case $entity instanceof \Drupal\node\Entity\Node:
      $user = $entity
        ->getOwner();
      $media = HeartBeat::mediaFieldTypes($entity
        ->getFields());
      if ($entity
        ->id() && $user
        ->isAuthenticated()) {
        $heartbeatTypeService = \Drupal::service('heartbeat.heartbeattype');
        $tokenService = \Drupal::service('token');
        foreach ($heartbeatTypeService
          ->getTypes() as $type) {
          $heartbeatTypeEntity = $heartbeatTypeService
            ->load($type);
          if ($heartbeatTypeEntity
            ->getMainEntity() == 'node') {
            $arguments = json_decode($heartbeatTypeEntity
              ->getArguments());
            foreach ($arguments as $key => $argument) {
              $variables[$key] = $argument;
            }
            $preparsedMessageString = strtr($heartbeatTypeEntity
              ->getMessage(), $variables);
            $entities = array(
              'node' => $entity,
              'user' => $user,
            );
            if ($entity
              ->bundle() === $heartbeatTypeEntity
              ->getBundle() && array_key_exists($heartbeatTypeEntity
              ->getBundle(), $heartbeatTypeService
              ->getEntityBundles($entity
              ->getEntityType()))) {
              $heartbeatMessage = Heartbeat::buildMessage($tokenService, $preparsedMessageString, $entities, $entity
                ->getEntityTypeId(), $media);
              $heartbeatActivity = Heartbeat::create([
                'type' => $heartbeatTypeEntity
                  ->id(),
                'uid' => $user
                  ->id(),
                'nid' => $entity
                  ->id(),
                'name' => $entity
                  ->getTitle(),
              ]);

              //TODO Find better fix than this str_replace
              $heartbeatActivity
                ->setMessage(str_replace('&039;', "'", $heartbeatMessage));
              if ($heartbeatActivity
                ->save()) {
                $bundleSaved = true;
              }
              continue;
            }
            else {
              if ($heartbeatTypeEntity
                ->getBundle() === null || trim($heartbeatTypeEntity
                ->getBundle()) === '') {
                $heartbeatMessage = Heartbeat::buildMessage($tokenService, $preparsedMessageString, $entities, $entity
                  ->getEntityTypeId(), $media);

                //      $translatedMessage = t($messageTemplate);
                $heartbeatActivity = Heartbeat::create([
                  'type' => $heartbeatTypeEntity
                    ->id(),
                  'uid' => $user
                    ->id(),
                  'nid' => $entity
                    ->id(),
                  'name' => $entity
                    ->getTitle(),
                  'status' => !$bundleSaved ? 1 : 0,
                ]);
                $heartbeatActivity
                  ->setMessage($heartbeatMessage);
                $heartbeatActivity
                  ->save();
              }
              else {
                continue;
              }
            }
          }
        }
        updateFeeds();
      }
      break;
    case $entity instanceof \Drupal\user\Entity\User:

      //      $userService = \Drupal\User\Entity\user
      break;
    case $entity instanceof \Drupal\flag\Entity\Flag:
      break;
    case $entity instanceof \Drupal\statusmessage\Entity\Status:
      $user = \Drupal\user\Entity\User::load($entity
        ->get('uid')
        ->getValue()[0]['target_id']);
      $heartbeatTypeService = \Drupal::service('heartbeat.heartbeattype');
      $tokenService = \Drupal::service('token');
      heartbeat_handle_entity($entity, $tokenService, $heartbeatTypeService, $user, 'status');
      break;
  }
}
function heartbeat_handle_entity($entity, $tokenService, $heartbeatTypeService, $user, $mainEntity) {
  $bundleSaved = false;
  if ($entity
    ->id() && $user
    ->isAuthenticated()) {
    $media = HeartBeat::mediaFieldTypes($entity
      ->getFields());
    foreach ($heartbeatTypeService
      ->getTypes() as $type) {
      $heartbeatTypeEntity = $heartbeatTypeService
        ->load($type);
      if ($heartbeatTypeEntity
        ->getMainEntity() == $mainEntity) {
        $arguments = json_decode($heartbeatTypeEntity
          ->getArguments());
        foreach ($arguments as $key => $argument) {
          $variables[$key] = $argument;
        }
        $preparsedMessageString = strtr($heartbeatTypeEntity
          ->getMessage(), $variables);
        $entities = array(
          $mainEntity => $entity,
          'user' => $user,
        );
        if ($entity
          ->bundle() === $heartbeatTypeEntity
          ->getBundle() && array_key_exists($heartbeatTypeEntity
          ->getBundle(), $heartbeatTypeService
          ->getEntityBundles($entity
          ->getEntityType()))) {
          $heartbeatMessage = Heartbeat::buildMessage($tokenService, $preparsedMessageString, $entities, $entity
            ->getEntityTypeId(), $media);
          $heartbeatActivity = Heartbeat::create([
            'type' => $heartbeatTypeEntity
              ->id(),
            'uid' => $user
              ->id(),
            'nid' => $entity
              ->id(),
            'name' => $entity
              ->getTitle(),
          ]);
          $heartbeatActivity
            ->setMessage($heartbeatMessage);
          if ($heartbeatActivity
            ->save()) {
            $bundleSaved = true;
          }
          continue;
        }
        else {
          if ($heartbeatTypeEntity
            ->getBundle() === null || trim($heartbeatTypeEntity
            ->getBundle()) === '') {
            $heartbeatMessage = Heartbeat::buildMessage($tokenService, $preparsedMessageString, $entities, $entity
              ->getEntityTypeId(), $media);

            //      $translatedMessage = t($messageTemplate);
            $heartbeatActivity = Heartbeat::create([
              'type' => $heartbeatTypeEntity
                ->id(),
              'uid' => $user
                ->id(),
              'nid' => $entity
                ->id(),
              'name' => $entity
                ->getName(),
              'status' => !$bundleSaved ? 1 : 0,
            ]);
            $heartbeatActivity
              ->setMessage(str_replace('&039;', "'", $heartbeatMessage));
            $heartbeatActivity
              ->save();
          }
          else {
            continue;
          }
        }
      }
    }
  }

  //  updateFeeds();
}
function updateFeeds() {

  //  $configFactory = \Drupal::service('config.factory');
}

/**
 * Implements hook_entity_view().
 */
function heartbeat_entity_view(array &$build, \Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode) {
  if ($entity instanceof \Drupal\user\Entity\User) {
    if (isset($build['flag_friendship']) && \Drupal::currentUser()
      ->id() === $entity
      ->id()) {
      \Drupal::logger('heartbeat_friendship_entityView')
        ->debug('IDs are %id1 and %id2', array(
        '%id1' => \Drupal::currentUser()
          ->id(),
        '%id2' => $entity
          ->id(),
      ));
      unset($build['flag_friendship']);
    }
  }
}

/**
 * Implements hook_cron().
 */
function heartbeat_cron() {

  //Iterate over the Heartbeat Types and ensure that the weight of bundle-specific types are lower than that of their

  //parent type. This will allow us to ensure Bundle specific types end up being published as opposed to

  //Types which represent all content types
  $heartbeatTypes = \Drupal::service('entity.query')
    ->get('heartbeat_type')
    ->condition('mainentity', 'node')
    ->execute();
  foreach ($heartbeatTypes as $heartbeatType) {
    $entity = \Drupal::service('entity_type.manager')
      ->getStorage('heartbeat_type')
      ->load($heartbeatType);
    if ($entity
      ->getBundle() === null) {
      $entity
        ->setWeight(99);
      $entity
        ->save();
    }
    else {
      $entity
        ->setWeight(0);
      $entity
        ->save();
    }
    if ($entity
      ->getMainEntity() === 'flagging') {
      $friendship = true;
      $flagService = \Drupal::service('flag');
      foreach ($flagService
        ->getAllFlags('user') as $flag) {
        if ($flag
          ->id() === 'friendship') {
          $flaggings = \Drupal\Core\Database\Database::getConnection()
            ->select('flagging', 'f')
            ->fields('f', array(
            'entity_id',
            'uid',
          ))
            ->condition('flag_id', $flag
            ->id())
            ->execute();
          foreach ($flaggings
            ->fetchAll() as $flagging) {
            $friendship = \Drupal\Core\Database\Database::getConnection()
              ->select('heartbeat_friendship', 'hf')
              ->fields(array(
              'status',
            ))
              ->condition('uid', $flagging->uid)
              ->condition('uid_target', $flagging->entity_id)
              ->execute();
            if ($friendship = $friendship
              ->fetchObject()) {
              $status = $friendship->status;
              $revFriendship = \Drupal\Core\Database\Database::getConnection()
                ->select('heartbeat_friendship', 'hf')
                ->fields(array(
                'status',
              ))
                ->condition('uid', $flagging->entity_id)
                ->condition('uid_target', $flagging->uid)
                ->execute();
              if ($revFriendship = $revFriendship
                ->fetchObject()) {
                $revStatus = $revFriendship->status;
              }
            }
          }
        }
      }
    }

    //      $entityQuery = \Drupal::service('entity.query')->get('flag
    //    foreach ($flagService->)
  }
  heartbeat_friendship_maintenance();
}
function heartbeat_friendship_maintenance() {
  $flagService = \Drupal::service('flag');
  $entityTypeManager = \Drupal::service('entity_type.manager');
  $flag = $flagService
    ->getFlagById('friendship');
  $friendships = Database::getConnection()
    ->select("heartbeat_friendship", "hf")
    ->fields('hf', array(
    'status',
    'uid',
    'uid_target',
  ))
    ->execute();
  foreach ($friendships
    ->fetchAll() as $friendship) {
    $revFriendship = Database::getConnection()
      ->select('heartbeat_friendship', 'hf')
      ->fields('hf', array(
      'status',
    ))
      ->condition('uid', $friendship->uid_target)
      ->condition('uid_target', $friendship->uid)
      ->execute();
    $revFriendResult = $revFriendship
      ->fetchField();
    if ($revFriendResult > -2) {
      if ($revFriendResult !== $friendship->status) {
        $update = Database::getConnection()
          ->update('heartbeat_friendship')
          ->fields(array(
          ':status' => 1,
        ))
          ->condition('uid', $friendship->uid)
          ->condition('uid_target', $friendship->uid_target);
        if ($updated = !$update
          ->execute()) {
          \Drupal::logger('Heartbeat Cron')
            ->error('Could not update status for friendship');
        }
      }
      if ($revFriendResult === $friendship->status || $updated) {
        $userEntity = $entityTypeManager
          ->getStorage('user')
          ->load($friendship->uid);
        $userTargetEntity = $entityTypeManager
          ->getStorage('user')
          ->load($friendship->uid_target);
        $flaggingFound = false;
        foreach ($flagService
          ->getEntityFlaggings($flag, $userTargetEntity) as $flagging) {
          $flOwner = $flagging
            ->getOwnerId();
          $usId = $userEntity
            ->id();
          $flaggableId = $flagging
            ->getFlaggableId();

          //TODO ownerId and entity Id seem to be reversed.
          if ($flagging
            ->getOwnerId() == $userEntity
            ->id() && $flagging
            ->getFlaggableId() == $friendship->uid_target) {
            $flaggingFound = true;
            break;
          }
        }
        if (!$flaggingFound) {
          $flagging = $flagService
            ->flag($flag, $userTargetEntity, $userEntity);
        }
        $flaggingReverseFound = false;
        foreach ($flagService
          ->getEntityFlaggings($flag, $userEntity) as $flagging) {
          if ($flagging
            ->getOwnerId() == $userTargetEntity
            ->id() && $flagging
            ->getFlaggableId() == $friendship->uid) {
            $flaggingReverseFound = true;
            break;
          }
        }
        if (!$flaggingReverseFound) {
          $flagging = $flagService
            ->flag($flag, $userEntity, $userTargetEntity);
        }

        //TODO update flagging values or create flaggings
      }
    }
    else {
      if ($friendship->status === 1) {

        //TODO Add reverse friendship
        $insertReverse = Database::getConnection()
          ->insert('heartbeat_friendship')
          ->fields([
          'uid' => $friendship->uid_target,
          'uid_target' => $friendship->uid,
          'created' => time(),
          'status' => 1,
        ]);
        if ($insertReverse
          ->execute()) {
          if ($friendship->status < 1) {
            $updateFriendship = Database::getConnection()
              ->update('heartbeat_friendship')
              ->fields(array(
              'status' => 1,
            ))
              ->condition('uid', $friendship->uid)
              ->condition('uid_target', $friendship->uid_target);
            if (!$updateFriendship
              ->execute()) {
              \Drupal::logger('Friendship update failed');
            }
          }
        }
        else {
          \Drupal::logger('Heartbeat')
            ->debug('Unable to insert or update for User with ID %id', [
            '%id' => $friendship->uid,
          ]);
        }
      }
      else {

        //TODO figure out how to set friendship pending
      }
    }
  }
}

/**
 * Implements hook_cron().
 */
function heartbeat_update_type_weight() {

  //Iterate over the Heartbeat Types and ensure that the weight of bundle-specific types are lower than that of their

  //parent type. This will allow us to ensure Bundle specific types end up being published as opposed to

  //Types which represent all content types
  $heartbeatTypes = \Drupal::service('entity.query')
    ->get('heartbeat_type')
    ->condition('mainentity', 'node')
    ->execute();
  if (count($heartbeatTypes) > 1) {
    foreach ($heartbeatTypes as $heartbeatType) {
      $entity = \Drupal::service('entity_type.manager')
        ->getStorage('heartbeat_type')
        ->load($heartbeatType);
      if ($entity
        ->getBundle() === null) {
        $entity
          ->setWeight(99);
        $entity
          ->save();
      }
      else {
        $entity
          ->setWeight(0);
        $entity
          ->save();
      }
    }
  }
}

/**
 * Implements hook_page_attachments_alter().
 */
function heartbeat_page_attachments_alter(array &$attachments) {
  $attachments['#attached']['library'][] = 'heartbeat/heartbeat';
}
function heartbeat_link_alter(&$variables) {
  if (!is_object($variables['text']) && $variables['text'] === 'Account Settings') {
    $token_service = \Drupal::token();
    $replacement = $token_service
      ->replace($variables['url']
      ->getUri(), [
      \Drupal::currentUser(),
    ]);
    unset($variables['url']);
    $url = Url::fromUserInput('/' . substr($replacement, 5));
    $variables['url'] = $url;
  }
}

/**
 * Implements hook_form_alter().
 */
function heartbeat_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $form['#attached']['drupalSettings']['admin'] = in_array('administrator', \Drupal::currentUser()
    ->getRoles());
}