Browse Source

So many changes, including fixed friendship

logicp 7 years ago
parent
commit
41723d51ce

+ 8 - 0
config/schema/heartbeat.schema.yml

@@ -84,3 +84,11 @@ heartbeat_update_feed.config:
     update:
       type: boolean
       label: 'Assert whether or not to update the feed'
+
+heartbeat_friendship.config:
+  type: config_object
+  label: 'Friendship States'
+  mapping:
+    data:
+      type: blob
+      label: 'Data structure comprising all of the friendship states for all users'

+ 245 - 29
heartbeat.module

@@ -279,17 +279,6 @@ function updateFeeds() {
 //  $curlQuery = '/heartbeat/update_feed/' . $updateFeedConfig->get('timestamp');
   //Set options for the curl request
 
-//  try {
-//    $response = \Drupal::httpClient()->get($curlQuery, array('headers' => array('Accept' => 'text/plain')));
-//    $data = (string) $response->getBody();
-//    if (empty($data)) {
-//      $stophere = null;
-//
-//    }
-//  }
-//  catch (RequestException $e) {
-//    return FALSE;
-//  }
 
 
 //  $curlOptions = array(
@@ -323,60 +312,287 @@ function updateFeeds() {
  */
 function heartbeat_ajax_render_alter(array &$data) {
 
+  $nullll = 'null';
+
+  $muhData = $data;
+
+  if ($data !== null) {
+
+    $saysomething = 'here';
+
+
+  }
 }
 
 /**
  * Implements hook_cron().
  */
 function heartbeat_cron() {
+  $friendship = false;
   //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);
+  foreach($heartbeatTypes as $heartbeatType) {
 
-      if ($entity->getBundle() === null) {
-        $entity->setWeight(99);
-        $entity->save();
-      } else {
-        $entity->setWeight(0);
-        $entity->save();
-      }
+    $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_flag_options_alter().
  */
 function heartbeat_flag_options_alter(array &$options, FlagInterface $flag) {
   $jigga = null;
 
-  $dis = 'the best';
+  \Drupal::logger('heartbeat')->debug('this is getting called');
 
-  $another = 'faggot';
 }
 
 /**
  * Implements hook_entity_bundle_create().
  */
-function heartbeat_entity_bundle_create($entity_type_id, $bundle)
-{
+function heartbeat_entity_bundle_create($entity_type_id, $bundle) {
 
 }
 
-//TODO Add heartbeat language to Javascript
-//TODO Determine necessity of polling
-//Add
+/**
+ * Implements hook_form_alter().
+ */
+function heartbeat_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
+  $muhId = $form_state;
+  $muhState = $form_id;
+
+  $jigganull  = 'naul';
+}
 
-//TODO implement polling in JS using Drupal Settings
+/**
+ * Implements hook_page_attachments_alter().
+ */
+function heartbeat_page_attachments_alter(array &$attachments) {
+
+    $jigganull  = 'naul';
+  $jiagganull  = 'naul';
+  $mattachments = $attachments;
+
+  $attachments['#attached']['library'][] = 'heartbeat/heartbeat';
+}
+
+/**
+ * Implements hook_flag_link_type_info_alter().
+ */
+function heartbeat_flag_link_type_info_alter(array &$link_types) {
+
+  $jigga = null;
+
+  \Drupal::logger('heartbeat')->debug('this is getting called');
+
+}
+
+
+/**
+ * Implements hook_flag_type_info_alter().
+ */
+function heartbeat_flag_type_info_alter(array &$definitions) {
+
+  $jigga = null;
+
+  \Drupal::logger('heartbeat')->debug('this is getting called');
+
+  $jsonDefs = json_encode($definitions);
+
+}
+
+/**
+ * Implements hook_preprocess().
+ */
+function heartbeat_preprocess(&$variables, $hook) {
+
+//  if ($hook === 'heartbeat') {
+//    foreach $
+//  }
+//  $myVaribale = 'varibale';
+//
+//  $otherVar = 'null';
+
+}
 //$variables['#attached']['drupalSettings']['heartbeatData'] = $mydata;
 //^ will become available in JS as:
 //settings.heartbeatData, data
+
+
+/**
+ * Implements hook_link_alter().
+ */
+function heartbeat_link_alter(&$variables) {
+
+  $jigga = null;
+
+  \Drupal::logger('heartbeat')->debug('Link alter is getting called');
+
+}
+
+
+/**
+ * Implements hook_entity_access().
+ */
+function heartbeat_entity_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account) {
+
+  $muhField = null;
+  $muhAccount = $account;
+
+  if ($entity !== null) {
+    $muhId = $entity->id();
+  }
+}

+ 4 - 0
heartbeat.services.yml

@@ -15,6 +15,10 @@ services:
     class: Drupal\heartbeat\HeartbeatService
     arguments: ['@entity_type.manager', '@entity.query', '@heartbeatstream']
 
+#  friendship:
+#    class: Drupal\heartbeat\FriendshipService
+#    arguments:
+
   heartbeat.event:
     class: Drupal\heartbeat\EventSubscriber\HeartbeatEventSubscriber
     arguments: ['@flag', '@heartbeat.heartbeattype', '@heartbeatstream', '@heartbeat']

+ 173 - 1
heartbeat.views.inc

@@ -12,6 +12,9 @@ use Drupal\Core\Render\Markup;
 use Drupal\field\FieldConfigInterface;
 use Drupal\field\FieldStorageConfigInterface;
 use Drupal\system\ActionConfigEntityInterface;
+use Drupal\views\Plugin\views\query\QueryPluginBase;
+use Drupal\views\ViewExecutable;
+use Drupal\views\Views;
 
 /**
 * Implements hook_views_data().
@@ -31,7 +34,176 @@ function heartbeat_views_data() {
         'field' => array(
             'id' => 'heartbeat_message_field',
         ),
-    );
+      );
+    // Base data.
+    $data = [];
+    $data['heartbeat_friendship'] = [];
+    $data['heartbeat_friendship']['table'] = [];
+    $data['heartbeat_friendship']['table']['group'] = t('Heartbeat Friendship');
+    $data['heartbeat_friendship']['table']['base'] = [
+        'field' =>  'id',
+        'title' => t('Friendships'),
+        'help' => t('Maintains friendship status between Users'),
+    //        'query_id' => 'teacher',
+
+    ];
+
+    // Fields.
+
+    $data['heartbeat_friendship']['id'] = [
+        'title' => t('id'),
+        'help' => t('Friendship ID'),
+        'field' => [
+            'id' => 'numeric',
+        ],
+        'sort' => array(
+            // ID of sort handler plugin to use.
+            'id' => 'standard',
+        ),
+
+        'filter' => array(
+            // ID of filter handler plugin to use.
+            'id' => 'numeric',
+        ),
+
+        'argument' => array(
+            // ID of argument handler plugin to use.
+            'id' => 'numeric',
+        ),
+    ];
+
+    $data['heartbeat_friendship']['uid'] = [
+        'title' => t('UID'),
+        'help' => t('User\'s Unique ID.'),
+        'field' => [
+            'id' => 'numeric',
+        ],
+        'sort' => array(
+            // ID of sort handler plugin to use.
+            'id' => 'standard',
+        ),
+
+        'filter' => array(
+            // ID of filter handler plugin to use.
+            'id' => 'numeric',
+        ),
+
+        'argument' => array(
+            // ID of argument handler plugin to use.
+            'id' => 'numeric',
+        ),
+        'relationship' => array(
+          'title' => t('User'),
+          'help' => t(''),
+          'base' => 'users_field_data',
+          'base field' => 'uid',
+          'id' => 'standard',
+        ),
+
+    ];
+
+    $data['heartbeat_friendship']['uid_target'] = [
+        'title' => t('UID Target'),
+        'help' => t('Unique ID of the User who is the target of the relationship'),
+        'field' => [
+            'id' => 'numeric',
+        ],
+        'sort' => array(
+            // ID of sort handler plugin to use.
+            'id' => 'standard',
+        ),
+
+        'filter' => array(
+            // ID of filter handler plugin to use.
+            'id' => 'numeric',
+        ),
+
+        'argument' => array(
+            // ID of argument handler plugin to use.
+            'id' => 'numeric',
+        ),
+        'relationship' => array(
+          'title' => t('User Target'),
+          'help' => t(''),
+          'base' => 'users_field_data',
+          'base field' => 'uid',
+          'id' => 'standard',
+        ),
+
+    ];
+
+    $data['heartbeat_friendship']['status'] = [
+        'title' => t('Status'),
+        'help' => t('The status of the friendship'),
+        'field' => [
+            'id' => 'numeric',
+        ],
+        'sort' => array(
+            // ID of sort handler plugin to use.
+            'id' => 'standard',
+        ),
+
+        'filter' => array(
+            // ID of filter handler plugin to use.
+            'id' => 'numeric',
+        ),
+
+        'argument' => array(
+            // ID of argument handler plugin to use.
+            'id' => 'numeric',
+        ),
+      ];
+
+  $data['heartbeat_friendship']['table']['join'] = [
+    'users_field_data' => [
+      'left_field' => 'uid',
+      'field' => 'uid',
+    ],
+  ];
+
+
 
     return $data;
 }
+
+/**
+ * Implements hook_views_query_alter().
+ * @param ViewExecutable $view
+ * @param QueryPluginBase $query
+ */
+function heartbeat_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
+
+  $thisstuff = 'stuff';
+
+  if ($view->id() == 'heartbeat_friendship') {
+    $thisjigga = null;
+//
+//    LEFT JOIN {two} ON one.field_a = two.field_b
+//Use this configuration:
+
+    $configuration = array(
+      'table' => 'users_field_data',
+      'field' => 'uid',
+      'left_table' => 'heartbeat_friendship',
+      'left_field' => 'uid_target',
+      'operator' => '=',
+    );
+    $join = Views::pluginManager('join')->createInstance('standard', $configuration);
+    $query->addRelationship('users_target', $join);
+
+  }
+}
+
+/**
+ * Implements hook_views_pre_render().
+ */
+//function heartbeat_views_pre_render(ViewExecutable $view) {
+
+//  $friendStatuses = [-1 => 'No Friendship', 0 => 'Pending Friendship', 1 => 'Minimum Bromance'];
+
+//  if ($view->id() === 'heartbeat_friendship') {
+//    foreach ($view->result as $row) {
+////      $row->heartbeat_friendship_status = $friendStatuses[$row->heartbeat_friendship_status];
+//    }
+//  }
+//}

+ 17 - 16
js/heartbeat.js

@@ -4,33 +4,39 @@
 (function($, Drupal, drupalSettings) {
     Drupal.behaviors.heartbeat = {
         attach: function (context, settings) {
-          console.dir(drupalSettings);
+
+          if (drupalSettings.friendData != null) {
+            var divs = document.querySelectorAll('.flag-friendship a.use-ajax');
+            divs.forEach(function (anchor) {
+              var userId = anchor.href.substring(anchor.href.indexOf('user') + 5, anchor.href.indexOf('&token'));
+              JSON.parse(drupalSettings.friendData).forEach(function (friendship) {
+                if (friendship.uid_target === userId && friendship.uid == drupalSettings.user.uid && friendship.status == 0) {
+                  anchor.innerHTML = 'Friendship Pending';
+                }
+              });
+            });
+          }
 
           feedElement = document.querySelector('.heartbeat-stream');
-          console.dir(feedElement);
 
           if (drupalSettings.feedUpdate == true) {
-            console.log('stop here man');
-
             updateFeed();
           }
 
             Drupal.AjaxCommands.prototype.selectFeed = function(ajax, response, status) {
-                console.log(response.feed);
-                console.dir(drupalSettings);
-                console.dir(context);
-                console.dir(settings);
 
               $.ajax({
                 type:'POST',
                 url:'/heartbeat/render_feed/' + response.feed,
                 success: function(response) {
-                  // feedElement = document.getElementById('block-heartbeatblock');
+
                   feedElement = document.querySelector('.heartbeat-stream');
                   console.dir(feedElement);
 
                   if (feedElement != null) {
+
                     feedElement.innerHTML = response;
+
                   } else {
 
                     feedBlock = document.getElementById('block-heartbeatblock');
@@ -39,11 +45,9 @@
                     feedBlock.appendChild(insertNode);
 
                   }
-                  console.dir(feedElement);
-                  console.dir(response);
+
                 }
               });
-              // #block-heartbeatblock
             };
 
             Drupal.AjaxCommands.prototype.updateFeed = function(ajax, response, status) {
@@ -53,10 +57,7 @@
                   type: 'POST',
                   url:'/heartbeat/update_feed/' + response.timestamp,
                   success: function(response) {
-                    // feedElement = document.getElementById('block-heartbeatblock');
-                    // feedElement = document.querySelector('.heartbeat-stream');
-                    // feedElement.innerHTML = response;
-                    // console.dir(feedElement);
+
                     console.dir(response);
                   }
                 });

+ 7 - 1
src/Controller/HeartbeatStreamController.php

@@ -89,7 +89,13 @@ class HeartbeatStreamController extends ControllerBase {
     $heartbeats = $this->heartbeatService->loadByTypes($heartbeatTypes);
 
     foreach($heartbeats as $heartbeat) {
-      $messages[] = $heartbeat->getMessage()->getValue()[0]['value'];
+//      $messages[] = $heartbeat->getMessage()->getValue()[0]['value'];
+
+      $entity = $this->entityTypeManager->getStorage('heartbeat')->load($heartbeat->id());
+      $view_builder = $this->entityTypeManager->getViewBuilder('heartbeat');
+      $pre_render = $view_builder->view($entity);
+      $render_output = render($pre_render);
+      $messages[] = $pre_render;
     }
     return [
       '#theme' => 'heartbeat_stream',

+ 21 - 15
src/Controller/TestController.php

@@ -3,6 +3,9 @@
 namespace Drupal\heartbeat\Controller;
 
 use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Database\Database;
+use Drupal\Core\Entity\EntityTypeManager;
+use Drupal\flag\FlagService;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\heartbeat\HeartbeatTypeServices;
 use Drupal\heartbeat\HeartbeatStreamServices;
@@ -33,9 +36,11 @@ class TestController extends ControllerBase {
   /**
    * {@inheritdoc}
    */
-  public function __construct(HeartbeatTypeServices $heartbeat_heartbeattype, HeartbeatStreamServices $heartbeatstream) {
+  public function __construct(HeartbeatTypeServices $heartbeat_heartbeattype, HeartbeatStreamServices $heartbeatstream, FlagService $flag_service, EntityTypeManager $entity_type_manager) {
     $this->heartbeat_heartbeattype = $heartbeat_heartbeattype;
     $this->heartbeatStream = $heartbeatstream;
+    $this->flagService = $flag_service;
+    $this->entityTypeManager = $entity_type_manager;
   }
 
   /**
@@ -44,7 +49,9 @@ class TestController extends ControllerBase {
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('heartbeat.heartbeattype'),
-      $container->get('heartbeatstream')
+      $container->get('heartbeatstream'),
+      $container->get('flag'),
+      $container->get('entity_type.manager')
 
     );
   }
@@ -53,25 +60,24 @@ class TestController extends ControllerBase {
    * Start.
    *
    * @return string
+   * @throws \InvalidArgumentException
+   * @throws \Drupal\Core\Database\IntegrityConstraintViolationException
+   * @throws \Drupal\Core\Database\DatabaseExceptionWrapper
+   * @throws \Drupal\Core\Database\InvalidQueryException
    *   Return Hello string.
    */
   public function start($arg) {
-    foreach ($this->heartbeatStream->getAllStreams() as $heartbeatStream) {
 
-      $route = new Route(
-        $heartbeatStream->getPath()->getValue()[0]['value'],
+    $friendships = Database::getConnection()->select("heartbeat_friendship", "hf")
+      ->fields('hf', array('status', 'uid', 'uid_target'))
+      ->execute();
 
-        array(
-          '_controller' => '\Drupal\heartbeat\Controller\HeartbeatStreamController::createRoute',
-          '_title' => $heartbeatStream->getName(),
-          'heartbeatStreamId' => $heartbeatStream->id(),
-        ),
-        array(
-          '_permission'  => 'access content',
-        )
-      );
+    $friendData = $friendships->fetchAll();
+
+    $friendConfig = \Drupal::configFactory()->getEditable('heartbeat_friendship.settings');
+
+    $friendConfig->set('data', json_encode($friendData))->save();
 
-    }
     return [
       '#type' => 'markup',
       '#markup' => $this->t('Implement method: start with parameter(s): ' . $arg),

+ 32 - 12
src/Entity/Heartbeat.php

@@ -303,8 +303,15 @@ class Heartbeat extends RevisionableContentEntityBase implements HeartbeatInterf
       ->setDescription(t('The content associated with this Heartbeat'))
       ->setSetting('target_type', 'node')
       ->setSetting('handler', 'default')
+      ->setDisplayOptions('view', array(
+        'label' => 'hidden',
+        'type' => 'content',
+        'weight' => 0,
+      ))
+      ->setDisplayConfigurable('view', TRUE)
       ->setRevisionable(TRUE);
 
+
     $fields['name'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Name'))
       ->setDescription(t('The name of the Heartbeat entity.'))
@@ -330,7 +337,14 @@ class Heartbeat extends RevisionableContentEntityBase implements HeartbeatInterf
     $fields['message'] = BaseFieldDefinition::create('string_long')
       ->setLabel(t('Message'))
       ->setDescription(t('The message of the Heartbeat entity.'))
-      ->setRevisionable(TRUE);
+      ->setRevisionable(TRUE)
+      ->setDisplayOptions('view', array(
+        'label' => 'above',
+        'type' => 'full_html',
+        'weight' => -4,
+      ))
+      ->setDisplayConfigurable('view', TRUE);
+
 
     $fields['status'] = BaseFieldDefinition::create('boolean')
       ->setLabel(t('Publishing status'))
@@ -416,7 +430,7 @@ class Heartbeat extends RevisionableContentEntityBase implements HeartbeatInterf
 
       case $entityType === 'node':
 
-        $parsedMessage = $tokenService->replace($preparsedMessage . '<a href="/node/[node:nid]">', $entities);
+        $parsedMessage = $tokenService->replace($preparsedMessage . '<a class="heartbeat-node" href="/node/[node:nid]">', $entities);
         /** @noinspection NestedTernaryOperatorInspection */
         $message = $parsedMessage;
         $message .= $mediaData ? self::buildMediaMarkup($mediaData) : '';
@@ -427,7 +441,7 @@ class Heartbeat extends RevisionableContentEntityBase implements HeartbeatInterf
 
       case $entityType === 'status':
 
-        $parsedMessage = $tokenService->replace($preparsedMessage . '<a href="/admin/structure/' . $entityType . '/[' . $entityType . ':id]">', $entities);
+        $parsedMessage = $tokenService->replace($preparsedMessage . '<a class="status-post" href="/admin/structure/' . $entityType . '/[' . $entityType . ':id]">', $entities);
         /** @noinspection NestedTernaryOperatorInspection */
         $message = $parsedMessage;
         $message .= $mediaData ? self::buildMediaMarkup($mediaData) : 'Post';
@@ -694,15 +708,21 @@ class Heartbeat extends RevisionableContentEntityBase implements HeartbeatInterf
       }
     }
     if ($friendStatus === 1) {
-      $insert2 = Database::getConnection()->insert('heartbeat_friendship')
-        ->fields([
-          'uid' => $uid_target,
-          'uid_target' => $uid,
-          'created' => $unixtime,
-          'status' => $friendStatus
-        ]);
-      if (!$insert2->execute()) {
-        \Drupal::logger('Heartbeat')->error('Unable to update friendship between %uid and %uid_target', array('%uid' => $uid_target, '%uid_target' => $uid));
+      $update2 = Database::getConnection()->update('heartbeat_friendship')
+        ->fields(['status' => $friendStatus])
+        ->condition('uid', $uid_target, '=')
+        ->condition('uid_target', $uid, '=');
+      if (!$update2->execute()) {
+        $insert2 = Database::getConnection()->insert('heartbeat_friendship')
+          ->fields([
+            'uid' => $uid_target,
+            'uid_target' => $uid,
+            'created' => $unixtime,
+            'status' => $friendStatus
+          ]);
+        if (!$insert2->execute()) {
+          \Drupal::logger('Heartbeat')->error('Unable to update friendship between %uid and %uid_target', array('%uid' => $uid_target, '%uid_target' => $uid));
+        }
       }
     }
   }

+ 63 - 10
src/EventSubscriber/HeartbeatEventSubscriber.php

@@ -4,6 +4,7 @@ namespace Drupal\heartbeat\EventSubscriber;
 
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 use Symfony\Component\EventDispatcher\Event;
+use Drupal\Core\Database\Database;
 use Drupal\flag\FlagService;
 use Drupal\user\Entity\User;
 use Drupal\heartbeat\Entity\Heartbeat;
@@ -139,13 +140,15 @@ class HeartbeatEventSubscriber implements EventSubscriberInterface {
       }
     }
 
-//    if ($friendStatus === FRIEND) {
-//      drupal_set_message($user->getUsername() . ' is now friends with ' . $user2->getUsername());
-//    } else if ($friendStatus === PENDING) {
-//      drupal_set_message($user->getUsername() . ' has requested friendship with ' . $user2->getUsername());
-//    } else {
-//      drupal_set_message($user->getUsername() . ' is unable to request friendship with ' . $user2->getUsername());
-//    }
+    $friendships = Database::getConnection()->select("heartbeat_friendship", "hf")
+      ->fields('hf', array('status', 'uid', 'uid_target'))
+      ->execute();
+
+    $friendData = $friendships->fetchAll();
+
+    $friendConfig = \Drupal::configFactory()->getEditable('heartbeat_friendship.settings');
+
+    $friendConfig->set('data', json_encode($friendData))->save();
   }
 
   /**
@@ -155,8 +158,58 @@ class HeartbeatEventSubscriber implements EventSubscriberInterface {
    * @param GetResponseEvent $event
    */
   public function flag_entity_unflagged(Event $event) {
-    $nothing = null;
-    drupal_set_message('Event flag.entity_unflagged thrown by Subscriber in module heartbeat.', 'status', TRUE);
-  }
 
+    $friendStatus = FRIEND;
+    $flagging = array_values($event->getFlaggings())[0];
+
+    if ($flagging->getFlagId() === 'friendship') {
+      $entity = $this->flagService->getFlagById($flagging->getFlagId());
+
+      $user = $flagging->getOwner();
+
+      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() === "flagging") {
+
+            $arguments = json_decode($heartbeatTypeEntity->getArguments());
+            $user2 = User::load($flagging->getFlaggableId());
+            $targetUserFriendships = $this->flagService->getFlagFlaggings($entity, $user2);
+
+            foreach ($targetUserFriendships as $friendship) {
+              if ($friendship->getFlaggableId() === $user->id()) {
+                $friendStatus = NOT_FRIEND;
+                break;
+              }
+            }
+
+            $friendStatus = $friendStatus == NOT_FRIEND ? NOT_FRIEND : PENDING;
+
+            foreach ($arguments as $key => $argument) {
+              $variables[$key] = $argument;
+            }
+
+            Heartbeat::updateFriendship($user->id(), $user2->id(), time(), $friendStatus);
+
+          }
+        }
+
+      }
+    }
+    $friendships = Database::getConnection()->select("heartbeat_friendship", "hf")
+      ->fields('hf', array('status', 'uid', 'uid_target'))
+      ->execute();
+
+    $friendData = $friendships->fetchAll();
+
+    $friendConfig = \Drupal::configFactory()->getEditable('heartbeat_friendship.settings');
+
+    $friendConfig->set('data', json_encode($friendData))->save();
+  }
 }

+ 1 - 1
src/Form/HeartbeatUpdateFeedForm.php

@@ -58,7 +58,7 @@ class HeartbeatUpdateFeedForm extends FormBase {
 //      $this->triggered = false;
 //      throw new \Drupal\heartbeat\Controller\HeartbeatAjaxException($this);
 //    }
-
+  //TODO this should be changed to library
     $form['#attached']['libraries'][] = 'heartbeat/heartbeat';
 
     $form['timestamp'] = [

+ 1 - 1
src/HeartbeatStreamServices.php

@@ -133,7 +133,7 @@ class HeartbeatStreamServices {
 
       if (count($beats) > 0) {
         $this->lastId = call_user_func('end', array_keys($beats));
-
+//TODO make this multiline
         $this->configFactory->getEditable('heartbeat_update_feed.settings')->set('lastId', $this->lastId)->set('update', false)->set('timestamp', array_values($beats)[0]->getRevisionCreationTime())->save();
 
         return $beats;

+ 5 - 1
src/Plugin/Block/HeartbeatBlock.php

@@ -85,6 +85,7 @@ class HeartbeatBlock extends BlockBase implements ContainerFactoryPluginInterfac
   public function build() {
 
     $myConfig = \Drupal::service('config.factory')->getEditable('heartbeat_feed.settings');
+    $friendData = \Drupal::config('heartbeat_friendship.settings')->get('data');
 
     $feed = $myConfig->get('message');
     $uids = null;
@@ -127,7 +128,10 @@ class HeartbeatBlock extends BlockBase implements ContainerFactoryPluginInterfac
         '#messages' => $messages,
         '#attached' => array(
           'library' => 'heartbeat/heartbeat',
-          'drupalSettings' => ['activeFeed' => 'jigga']
+          'drupalSettings' => [
+            'activeFeed' => 'jigga',
+            'friendData' => $friendData,
+          ]
         ),
         '#cache' => array('max-age' => 0)
       ];

+ 3 - 0
templates/heartbeat.html.twig

@@ -18,5 +18,8 @@
 <div{{ attributes.addClass('heartbeat') }}>
   {% if content %}
     {{- content -}}
+    {% autoescape false %}
+      {{ content.message | raw }}
+    {% endautoescape %}
   {% endif %}
 </div>