View source
<?php
namespace Drupal\social_private_message\Service;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\Entity;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\private_message\Mapper\PrivateMessageMapperInterface;
use Drupal\private_message\Service\PrivateMessageService;
use Drupal\user\UserDataInterface;
class SocialPrivateMessageService extends PrivateMessageService {
protected $database;
public function __construct(PrivateMessageMapperInterface $mapper, AccountProxyInterface $currentUser, ConfigFactoryInterface $configFactory, UserDataInterface $userData, CacheTagsInvalidatorInterface $cacheTagsInvalidator, EntityTypeManagerInterface $entityTypeManager, TimeInterface $time, Connection $database) {
parent::__construct($mapper, $currentUser, $configFactory, $userData, $cacheTagsInvalidator, $entityTypeManager, $time);
$this->database = $database;
}
public function updateLastThreadCheckTime(Entity $entity) {
$this->userData
->set('private_message', $this->currentUser
->id(), 'private_message_thread:' . $entity
->id(), $this->time
->getRequestTime());
}
public function deleteUserDataThreadInfo(Entity $entity) {
$this->userData
->delete('private_message', $this->currentUser
->id(), 'private_message_thread:' . $entity
->id());
}
public function updateUnreadCount() {
$unread = 0;
$uid = $this->currentUser
->id();
$threads = $this
->getAllThreadIdsForUser($uid);
if (empty($threads)) {
return $unread;
}
$thread_last_messages = $this
->getLastMessagesFromOtherUsers($uid, $threads);
if (empty($thread_last_messages)) {
return $unread;
}
foreach ($thread_last_messages as $thread_id => $last_message) {
$thread_last_check = $this->userData
->get('private_message', $uid, 'private_message_thread:' . $thread_id);
if ($thread_last_check === NULL) {
$thread_last_check = 0;
}
if ($last_message > $thread_last_check) {
$unread++;
}
}
return $unread;
}
public function getAllThreadIdsForUser($uid) {
$query = 'SELECT DISTINCT(thread.id), MAX(thread.updated) ' . 'FROM {private_message_threads} AS thread ' . 'JOIN {private_message_thread__members} AS member ' . 'ON member.entity_id = thread.id AND member.members_target_id = :uid ' . 'JOIN {private_message_thread__private_messages} AS thread_messages ' . 'ON thread_messages.entity_id = thread.id ' . 'JOIN {private_messages} AS messages ' . 'ON messages.id = thread_messages.private_messages_target_id ' . 'JOIN {private_message_thread__last_delete_time} AS thread_delete_time ' . 'ON thread_delete_time.entity_id = thread.id ' . 'JOIN {pm_thread_delete_time} as owner_delete_time ' . 'ON owner_delete_time.id = thread_delete_time.last_delete_time_target_id AND owner_delete_time.owner = :uid ' . 'WHERE owner_delete_time.delete_time <= messages.created ';
$vars = [
':uid' => $uid,
];
$query .= 'GROUP BY thread.id ORDER BY MAX(thread.updated) DESC, thread.id';
$thread_ids = $this->database
->query($query, $vars)
->fetchCol();
return is_array($thread_ids) ? $thread_ids : [];
}
public function getLastMessagesFromOtherUsers($uid, array $threads) {
return $this->database
->query('SELECT MAX(pm.created), pmt.entity_id ' . 'FROM {private_message_thread__private_messages} pmt ' . 'LEFT JOIN {private_messages} pm ON pmt.private_messages_target_id = pm.id ' . 'WHERE pmt.entity_id IN (:threads[]) AND pm.owner <> :uid ' . 'GROUP BY pmt.entity_id', [
':threads[]' => $threads,
':uid' => $uid,
])
->fetchAllKeyed(1, 0);
}
public function getLastMessageFromOtherUser($uid, $thread_id) {
$timestamp = $this->database
->query('SELECT MAX(pm.created) ' . 'FROM {private_message_thread__private_messages} pmt ' . 'JOIN {private_messages} pm ON pmt.private_messages_target_id = pm.id ' . 'WHERE pmt.entity_id = :thread AND pm.owner <> :uid', [
':thread' => $thread_id,
':uid' => $uid,
])
->fetchCol();
if (is_array($timestamp)) {
$timestamp = $timestamp[0] !== NULL ? $timestamp[0] : 0;
}
return $timestamp;
}
}