getEntityManager()->getEntity('Notification'); $notification->set(array( 'type' => 'MentionInPost', 'data' => array('noteId' => $noteId), 'userId' => $userId, 'relatedId' => $noteId, 'relatedType' => 'Note' )); $this->getEntityManager()->saveEntity($notification); } public function notifyAboutNote(array $userIdList, Note $note) { $data = ['noteId' => $note->id]; $encodedData = Json::encode($data); $related = null; if ($note->get('relatedType') == 'Email') { $related = $this->getEntityManager()->getRepository('Email') ->select(['id', 'sentById', 'createdById'])->where(['id' => $note->get('relatedId')])->findOne(); } $now = date('Y-m-d H:i:s'); $pdo = $this->getEntityManager()->getPDO(); $query = $this->getEntityManager()->getQuery(); $sql = "INSERT INTO `notification` (`id`, `data`, `type`, `user_id`, `created_at`, `related_id`, `related_type`, `related_parent_id`, `related_parent_type`) VALUES "; $arr = []; $userList = $this->getEntityManager()->getRepository('User')->where([ 'isActive' => true, 'id' => $userIdList ])->find(); foreach ($userList as $user) { $userId = $user->id; if (!$this->checkUserNoteAccess($user, $note)) continue; if ($note->get('createdById') === $user->id) continue; if ($related && $related->getEntityType() == 'Email' && $related->get('sentById') == $user->id) continue; if ($related && $related->get('createdById') == $user->id) continue; $id = \Espo\Core\Utils\Util::generateId(); $arr[] = "(".$query->quote($id).", ".$query->quote($encodedData).", ".$query->quote('Note').", ".$query->quote($userId).", ".$query->quote($now).", ".$query->quote($note->id).", ".$query->quote('Note').", ".$query->quote($note->get('parentId')).", ".$query->quote($note->get('parentType')).")"; } if (empty($arr)) return; $sql .= implode(", ", $arr); $pdo->query($sql); if ($this->getConfig()->get('useWebSocket')) { foreach ($userIdList as $userId) { $this->webSocketSubmission->submit('newNotification', $userId); } } } public function checkUserNoteAccess(User $user, Note $note) : bool { if ($user->isPortal()) { if ($note->get('relatedType')) { if ($note->get('relatedType') === 'Email' && $note->get('parentType') === 'Case') { return true; } return false; } return true; } if ($note->get('relatedType')) { if (!$this->getAclManager()->checkScope($user, $note->get('relatedType'))) { return false; } } if ($note->get('parentType')) { if (!$this->getAclManager()->checkScope($user, $note->get('parentType'))) { return false; } } return true; } public function getNotReadCount(string $userId) : int { $whereClause = array( 'userId' => $userId, 'read' => 0 ); $ignoreScopeList = $this->getIgnoreScopeList(); if (!empty($ignoreScopeList)) { $where = []; $where[] = array( 'OR' => array( 'relatedParentType' => null, 'relatedParentType!=' => $ignoreScopeList ) ); $whereClause[] = $where; } return $this->getEntityManager()->getRepository('Notification')->where($whereClause)->count(); } public function markAllRead(string $userId) { $pdo = $this->getEntityManager()->getPDO(); $sql = "UPDATE notification SET `read` = 1 WHERE user_id = ".$pdo->quote($userId)." AND `read` = 0"; $pdo->prepare($sql)->execute(); return true; } public function getList(string $userId, array $params = []) : RecordCollection { $searchParams = []; $whereClause = [ 'userId' => $userId ]; if (!empty($params['after'])) { $whereClause['createdAt>'] = $params['after']; } $ignoreScopeList = $this->getIgnoreScopeList(); if (!empty($ignoreScopeList)) { $where = []; $where[] = [ 'OR' => [ 'relatedParentType' => null, 'relatedParentType!=' => $ignoreScopeList ] ]; $whereClause[] = $where; } $searchParams['whereClause'] = $whereClause; if (array_key_exists('offset', $params)) { $searchParams['offset'] = $params['offset']; } if (array_key_exists('maxSize', $params)) { $searchParams['limit'] = $params['maxSize']; } $searchParams['orderBy'] = 'createdAt'; $searchParams['order'] = 'DESC'; $collection = $this->getEntityManager()->getRepository('Notification')->find($searchParams); $count = $this->getEntityManager()->getRepository('Notification')->count($searchParams); $ids = []; foreach ($collection as $k => $entity) { $ids[] = $entity->id; $data = $entity->get('data'); if (empty($data)) { continue; } switch ($entity->get('type')) { case 'Note': case 'MentionInPost': $note = $this->getEntityManager()->getEntity('Note', $data->noteId); if ($note) { if ($note->get('parentId') && $note->get('parentType')) { $parent = $this->getEntityManager()->getEntity($note->get('parentType'), $note->get('parentId')); if ($parent) { $note->set('parentName', $parent->get('name')); } } else { if (!$note->get('isGlobal')) { $targetType = $note->get('targetType'); if (!$targetType || $targetType === 'users') { $note->loadLinkMultipleField('users'); } if ($targetType !== 'users') { if (!$targetType || $targetType === 'teams') { $note->loadLinkMultipleField('teams'); } else if ($targetType === 'portals') { $note->loadLinkMultipleField('portals'); } } } } if ($note->get('relatedId') && $note->get('relatedType')) { $related = $this->getEntityManager()->getEntity($note->get('relatedType'), $note->get('relatedId')); if ($related) { $note->set('relatedName', $related->get('name')); } } $note->loadLinkMultipleField('attachments'); $entity->set('noteData', $note->toArray()); } else { unset($collection[$k]); $count--; $this->getEntityManager()->removeEntity($entity); } break; } } if (!empty($ids)) { $pdo = $this->getEntityManager()->getPDO(); $idQuotedList = []; foreach ($ids as $id) { $idQuotedList[] = $pdo->quote($id); } $sql = "UPDATE notification SET `read` = 1 WHERE id IN (" . implode(', ', $idQuotedList) .")"; $s = $pdo->prepare($sql); $s->execute(); } return new RecordCollection($collection, $count); } protected function getIgnoreScopeList() : array { $ignoreScopeList = []; $scopes = $this->getMetadata()->get('scopes', []); foreach ($scopes as $scope => $d) { if (empty($d['entity']) || !$d['entity']) continue; if (empty($d['object']) || !$d['object']) continue; if (!$this->getAcl()->checkScope($scope)) { $ignoreScopeList[] = $scope; } } return $ignoreScopeList; } }