notification about mention

This commit is contained in:
yuri
2016-06-23 16:18:32 +03:00
parent 610922c8e0
commit 7d667a1d1b
15 changed files with 212 additions and 9 deletions

View File

@@ -0,0 +1,42 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Jobs;
use \Espo\Core\Exceptions;
class SendEmailNotifications extends \Espo\Core\Jobs\Base
{
public function run()
{
$service = $this->getServiceFactory()->create('EmailNotification');
$service->process();
}
}

View File

@@ -407,6 +407,9 @@ abstract class Base
}
if (!is_null($order)) {
if (is_bool($order)) {
$order = $order ? 'DESC' : 'ASC';
}
$order = strtoupper($order);
if (!in_array($order, ['ASC', 'DESC'])) {
$order = 'ASC';

View File

@@ -18,7 +18,8 @@
"smtpPassword": "Password",
"smtpEmailAddress": "Email Address",
"exportDelimiter": "Export Delimiter",
"receiveAssignmentEmailNotifications": "Receive Email Notifications upon Assignment",
"receiveAssignmentEmailNotifications": "Receive email notifications upon assignment",
"receiveMentionEmailNotifications": "Receive email notifications about mentions in posts",
"autoFollowEntityTypeList": "Auto-Follow",
"signature": "Email Signature",
"dashboardTabList": "Tab List",

View File

@@ -17,7 +17,8 @@
"CheckInboundEmails": "Check Group Email Accounts",
"CheckEmailAccounts": "Check Personal Email Accounts",
"SendEmailReminders": "Send Email Reminders",
"AuthTokenControl": "Auth Token Control"
"AuthTokenControl": "Auth Token Control",
"SendEmailNotifications": "Send Email Notifications"
},
"cronSetup": {
"linux": "Note: Add this line to the crontab file to run Espo Scheduled Jobs:",

View File

@@ -46,9 +46,9 @@
"ldapAccountDomainNameShort": "Account Domain Name Short",
"ldapOptReferrals": "Opt Referrals",
"exportDisabled": "Disable Export (only admin is allowed)",
"assignmentNotificationsEntityList": "Entities to Notify about upon Assignment",
"assignmentEmailNotifications": "Send Email Notifications upon Assignment",
"assignmentEmailNotificationsEntityList": "Entities to Notify about with Email upon Assignment",
"assignmentNotificationsEntityList": "Entities to notify about upon assignment",
"assignmentEmailNotifications": "Send email notifications upon assignment",
"assignmentEmailNotificationsEntityList": "Entities to notify about with email upon assignment",
"b2cMode": "B2C Mode",
"avatarsDisabled": "Disable Avatars",
"followCreatedEntities": "Follow Created Entities",
@@ -68,7 +68,8 @@
"addressFormat": "Address Format",
"notificationSoundsDisabled": "Disable Notification Sounds",
"applicationName": "Application Name",
"calendarEntityList": "Calendar Entity List"
"calendarEntityList": "Calendar Entity List",
"mentionEmailNotifications": "Send email notifications about mentions in posts"
},
"options": {
"weekStart": {

View File

@@ -71,7 +71,7 @@
{
"label": "Notifications",
"rows": [
[{"name": "receiveAssignmentEmailNotifications"}, false]
[{"name": "receiveAssignmentEmailNotifications"}, {"name": "receiveMentionEmailNotifications"}]
]
}
]

View File

@@ -9,7 +9,7 @@
{
"label": "Email Notifications",
"rows": [
[{"name": "assignmentEmailNotifications"}],
[{"name": "assignmentEmailNotifications"}, {"name": "mentionEmailNotifications"}],
[{"name": "assignmentEmailNotificationsEntityList"}]
]
}

View File

@@ -17,6 +17,9 @@
"read": {
"type": "bool"
},
"emailIsProcessed": {
"type": "bool"
},
"user": {
"type": "link"
},

View File

@@ -98,6 +98,10 @@
"type": "bool",
"default": true
},
"receiveMentionEmailNotifications": {
"type": "bool",
"default": true
},
"autoFollowEntityTypeList": {
"type": "multiEnum",
"view": "views/preferences/fields/auto-follow-entity-type-list",

View File

@@ -64,6 +64,7 @@
"CheckEmailAccounts": "*/5 * * * *",
"SendEmailReminders": "/2 * * * *",
"Cleanup": "1 1 * * 0",
"AuthTokenControl": "*/6 * * * *"
"AuthTokenControl": "*/6 * * * *",
"SendEmailNotifications": "/2 * * * *"
}
}

View File

@@ -223,6 +223,10 @@
"translation": "Global.scopeNamesPlural",
"view": "views/settings/fields/assignment-notifications-entity-list"
},
"mentionEmailNotifications": {
"type": "bool",
"default": false
},
"b2cMode": {
"type": "bool",
"default": false

View File

@@ -0,0 +1,6 @@
<p>You were mentioned in post by {{userName}}.</p>
{{#if parentName}}
<p>Related to: {{parentName}}</p>
{{/if}}
<p>{{{post}}}</p>
<p><a href="{{url}}">View</a></p>

View File

@@ -0,0 +1 @@
You were mentioned

View File

@@ -36,6 +36,8 @@ use Espo\ORM\Entity;
class EmailNotification extends \Espo\Core\Services\Base
{
const HOURS_THERSHOLD = 5;
protected function init()
{
$this->addDependencyList([
@@ -186,4 +188,132 @@ class EmailNotification extends \Espo\Core\Services\Base
$fileName = "application/Espo/Resources/templates/{$type}/{$language}/{$name}.tpl";
return $fileName;
}
protected function getMentionTemplate($name)
{
$fileName = $this->getMentionTemplateFileName($name);
return file_get_contents($fileName);
}
protected function getMentionTemplateFileName($name)
{
$language = $this->getConfig()->get('language');
$type = 'mention';
$fileName = "custom/Espo/Custom/Resources/templates/{$type}/{$language}/{$name}.tpl";
if (file_exists($fileName)) return $fileName;
$fileName = "application/Espo/Resources/templates/{$type}/{$language}/{$name}.tpl";
if (file_exists($fileName)) return $fileName;
$language = 'en_US';
$fileName = "custom/Espo/Custom/Resources/templates/{$type}/{$language}/{$name}.tpl";
if (file_exists($fileName)) return $fileName;
$fileName = "application/Espo/Resources/templates/{$type}/{$language}/{$name}.tpl";
return $fileName;
}
public function process()
{
$dateTime = new \DateTime();
$dateTime->modify('-' . self::HOURS_THERSHOLD . ' hours');
$mentionEmailNotifications = $this->getConfig()->get('mentionEmailNotifications');
$typeList = [];
if ($mentionEmailNotifications) {
$typeList[] = 'MentionInPost';
}
if (!$mentionEmailNotifications) return;
$where = array(
'createdAt' > $dateTime,
'read' => false,
'emailIsProcessed' => false
);
$where['type'] = $typeList;
$notificationList = $this->getEntityManager()->getRepository('Notification')->where($where)->order('createdAt')->find();
foreach ($notificationList as $notification) {
$notification->set('emailIsProcessed', true);
$type = $notification->get('type');
$methodName = 'processNotification' . ucfirst($type);
if (method_exists($this, $methodName)) {
$this->$methodName($notification);
}
$this->getEntityManager()->saveEntity($notification);
}
}
public function processNotificationMentionInPost(Entity $notification)
{
$userId = $notification->get('userId');
$user = $this->getEntityManager()->getEntity('User', $userId);
$emailAddress = $user->get('emailAddress');
if (!$emailAddress) return;
$preferences = $this->getEntityManager()->getEntity('Preferences', $userId);
if (!$preferences) return;
if (!$preferences->get('receiveMentionEmailNotifications')) return;
if ($notification->get('relatedType') !== 'Note' || !$notification->get('relatedId')) return;
$note = $this->getEntityManager()->getEntity('Note', $notification->get('relatedId'));
if (!$note) return;
$post = $note->get('post');
$parentId = $note->get('parentId');
$parentType = $note->get('parentType');
$data = array();
if ($parentId && $parentType) {
$parent = $this->getEntityManager()->getEntity($parentType, $parentId);
if (!$parent) return;
$data['url'] = rtrim($this->getConfig()->get('siteUrl'), '/') . '/#' . $parentType . '/' . $parentId;
$data['parentName'] = $parent->get('name');
$data['parentType'] = $parentType;
$data['parentId'] = $parentId;
} else {
$data['url'] = rtrim($this->getConfig()->get('siteUrl'), '/') . '/#Notification';
}
$data['userName'] = $note->get('createdByName');
$data['post'] = $note->get('post');
$subjectTpl = $this->getMentionTemplate('subject');
$bodyTpl = $this->getMentionTemplate('body');
$subjectTpl = str_replace(array("\n", "\r"), '', $subjectTpl);
$subject = $this->getHtmlizer()->render($note, $subjectTpl, 'mention-email-subject', $data, true);
$body = $this->getHtmlizer()->render($note, $bodyTpl, 'mention-email-body', $data, true);
$email = $this->getEntityManager()->getEntity('Email');
$email->set(array(
'subject' => $subject,
'body' => $body,
'isHtml' => true,
'to' => $emailAddress,
'isSystem' => true
));
try {
$this->getMailSender()->send($email);
} catch (\Exception $e) {
$GLOBALS['log']->error('EmailNotification: [' . $e->getCode() . '] ' .$e->getMessage());
}
}
}

View File

@@ -55,6 +55,12 @@ return array(
'status' => 'Active',
'scheduling' => '*/2 * * * *',
),
array(
'name' => 'Send Email Notifications',
'job' => 'SendEmailNotifications',
'status' => 'Active',
'scheduling' => '*/2 * * * *',
),
array(
'name' => 'Clean-up',
'job' => 'Cleanup',