refactoring

This commit is contained in:
Yuri Kuznetsov
2021-04-04 19:55:08 +03:00
parent eadf3b46e0
commit 9cb8d9d65e
6 changed files with 361 additions and 261 deletions
@@ -51,13 +51,17 @@ class OwnerUserFieldProvider
$this->metadata = $metadata;
}
/**
* Get an entity field that stores an owner-user (or multiple users).
* Must be link or linkMulitple field. NULL means no owner.
*/
public function get(string $entityType) : ?string
{
$value = $this->metadata->get(['entityAcl', $entityType, 'readOwnerUserField']);
if ($value) {
return $value;
}
}
$defs = $this->ormDefs->getEntity($entityType);
+147 -66
View File
@@ -29,8 +29,6 @@
namespace Espo\Core\Mail;
use Laminas\Mime\Mime as Mime;
use Espo\Entities\Email;
use Espo\Core\{
@@ -41,8 +39,6 @@ use Espo\Core\{
Mail\Parsers\MailMimeParser,
};
use Espo\Notificators\EmailNotificator;
use DateTime;
use DateTimeZone;
use Exception;
@@ -65,7 +61,10 @@ class Importer
protected $parserClassName;
public function __construct(
EntityManager $entityManager, Config $config, ?Notificator $notificator = null, ?string $parserClassName = null
EntityManager $entityManager,
Config $config,
?Notificator $notificator = null,
?string $parserClassName = null
) {
$this->entityManager = $entityManager;
$this->config = $config;
@@ -85,6 +84,7 @@ class Importer
bool $fetchOnlyHeader = false,
?array $folderData = null
) : ?Email {
$parser = $message->getParser();
$parserClassName = $this->parserClassName;
@@ -134,13 +134,16 @@ class Importer
if ($fromAddressData) {
$fromString = ($fromAddressData['name'] ? ($fromAddressData['name'] . ' ') : '') . '<' .
$fromAddressData['address'] .'>';
$email->set('fromString', $fromString);
}
$replyToData = $parser->getAddressDataFromMessage($message, 'reply-To');
if ($replyToData) {
$replyToString = ($replyToData['name'] ? ($replyToData['name'] . ' ') : '') . '<' . $replyToData['address'] .'>';
$replyToString = ($replyToData['name'] ? ($replyToData['name'] . ' ') : '') .
'<' . $replyToData['address'] .'>';
$email->set('replyToString', $replyToString);
}
@@ -170,13 +173,19 @@ class Importer
return null;
}
if ($parser->checkMessageAttribute($message, 'message-Id') && $parser->getMessageAttribute($message, 'message-Id')) {
if (
$parser->checkMessageAttribute($message, 'message-Id') &&
$parser->getMessageAttribute($message, 'message-Id')
) {
$messageId = $parser->getMessageMessageId($message);
$email->set('messageId', $messageId);
if ($parser->checkMessageAttribute($message, 'delivered-To')) {
$email->set('messageIdInternal', $messageId . '-' . $parser->getMessageAttribute($message, 'delivered-To'));
$email->set(
'messageIdInternal',
$messageId . '-' . $parser->getMessageAttribute($message, 'delivered-To')
);
}
if (stripos($messageId, '@espo-system') !== false) {
@@ -184,9 +193,9 @@ class Importer
}
}
$duplicate = null;
$duplicate = $this->findDuplicate($email);
if ($duplicate = $this->findDuplicate($email)) {
if ($duplicate) {
if ($duplicate->get('status') != 'Being Imported') {
$duplicate = $this->entityManager->getEntity('Email', $duplicate->id);
@@ -202,10 +211,13 @@ class Importer
if ($dt) {
$dateSent = $dt->setTimezone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s');
$email->set('dateSent', $dateSent);
}
} catch (Exception $e) {}
} else {
}
catch (Exception $e) {}
}
else {
$email->set('dateSent', date('Y-m-d H:i:s'));
}
@@ -215,9 +227,11 @@ class Importer
if ($dt) {
$deliveryDate = $dt->setTimezone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s');
$email->set('delivery-Date', $deliveryDate);
}
} catch (Exception $e) {}
}
catch (Exception $e) {}
}
$inlineAttachmentList = [];
@@ -228,7 +242,8 @@ class Importer
if ($this->filtersMatcher->match($email, $filterList)) {
return null;
}
} else {
}
else {
$email->set('body', 'Not fetched. The email size exceeds the limit.');
$email->set('isHtml', false);
}
@@ -238,9 +253,11 @@ class Importer
$replied = null;
if (
$parser->checkMessageAttribute($message, 'in-Reply-To') && $parser->getMessageAttribute($message, 'in-Reply-To')
$parser->checkMessageAttribute($message, 'in-Reply-To') &&
$parser->getMessageAttribute($message, 'in-Reply-To')
) {
$arr = explode(' ', $parser->getMessageAttribute($message, 'in-Reply-To'));
$inReplyTo = $arr[0];
if ($inReplyTo) {
@@ -258,6 +275,7 @@ class Importer
if ($replied) {
$email->set('repliedId', $replied->id);
$repliedTeamIdList = $replied->getLinkMultipleIdList('teams');
foreach ($repliedTeamIdList as $repliedTeamId) {
$email->addLinkMultipleId('teams', $repliedTeamId);
}
@@ -265,7 +283,10 @@ class Importer
}
}
if ($parser->checkMessageAttribute($message, 'references') && $parser->getMessageAttribute($message, 'references')) {
if (
$parser->checkMessageAttribute($message, 'references') &&
$parser->getMessageAttribute($message, 'references')
) {
$references = $parser->getMessageAttribute($message, 'references');
$delimiter = ' ';
@@ -278,6 +299,7 @@ class Importer
foreach ($arr as $reference) {
$reference = trim($reference);
$reference = str_replace(['/', '@'], " ", trim($reference, '<>'));
$parentType = $parentId = null;
$emailSent = PHP_INT_MAX;
$number = null;
@@ -295,15 +317,20 @@ class Importer
if ($parent && $parent->get('status') == 'Converted') {
if ($parent->get('createdAccountId')) {
$account = $this->entityManager->getEntity('Account', $parent->get('createdAccountId'));
$account = $this->entityManager
->getEntity('Account', $parent->get('createdAccountId'));
if ($account) {
$parentType = 'Account';
$parentId = $account->id;
}
} else {
}
else {
if ($this->config->get('b2cMode')) {
if ($parent->get('createdContactId')) {
$contact = $this->entityManager->getEntity('Contact', $parent->get('createdContactId'));
$contact = $this->entityManager
->getEntity('Contact', $parent->get('createdContactId'));
if ($contact) {
$parentType = 'Contact';
$parentId = $contact->id;
@@ -325,7 +352,8 @@ class Importer
if (!$parentFound) {
if ($replied && $replied->get('parentId') && $replied->get('parentType')) {
$parentFound = $this->entityManager->getEntity($replied->get('parentType'), $replied->get('parentId'));
$parentFound = $this->entityManager
->getEntity($replied->get('parentType'), $replied->get('parentId'));
if ($parentFound) {
$email->set('parentType', $replied->get('parentType'));
@@ -340,11 +368,13 @@ class Importer
$parentFound = $this->findParent($email, $from);
}
}
if (!$parentFound) {
if (!empty($replyToArr)) {
$parentFound = $this->findParent($email, $replyToArr[0]);
}
}
if (!$parentFound) {
if (!empty($toArr)) {
$parentFound = $this->findParent($email, $toArr[0]);
@@ -359,6 +389,7 @@ class Importer
if ($duplicate->get('status') != 'Being Imported') {
$duplicate = $this->entityManager->getEntity('Email', $duplicate->id);
$this->processDuplicate($duplicate, $assignedUserId, $userIdList, $folderData, $teamsIdList);
return $duplicate;
@@ -408,12 +439,17 @@ class Importer
if ($parentFound) {
$parentType = $email->get('parentType');
$parentId = $email->get('parentId');
$emailKeepParentTeamsEntityList = $this->config->get('emailKeepParentTeamsEntityList', []);
if ($parentId && in_array($parentType, $emailKeepParentTeamsEntityList)) {
if ($this->entityManager->hasRepository($parentType)) {
$parent = $this->entityManager->getEntity($parentType, $parentId);
if ($parent) {
$parentTeamIdList = $parent->getLinkMultipleIdList('teams');
foreach ($parentTeamIdList as $parentTeamId) {
$email->addLinkMultipleId('teams', $parentTeamId);
}
@@ -434,61 +470,75 @@ class Importer
'relatedType' => 'Email',
'field' => 'body',
]);
$this->entityManager->saveEntity($attachment);
}
return $email;
}
protected function findParent(Email $email, $emailAddress)
protected function findParent(Email $email, $emailAddress): bool
{
$contact = $this->entityManager->getRepository('Contact')->where([
'emailAddress' => $emailAddress
])->findOne();
$contact = $this->entityManager
->getRepository('Contact')
->where([
'emailAddress' => $emailAddress
])
->findOne();
if ($contact) {
if (!$this->config->get('b2cMode')) {
if ($contact->get('accountId')) {
$email->set('parentType', 'Account');
$email->set('parentId', $contact->get('accountId'));
if (!$this->config->get('b2cMode') && $contact->get('accountId')) {
$email->set('parentType', 'Account');
$email->set('parentId', $contact->get('accountId'));
return true;
}
return true;
}
$email->set('parentType', 'Contact');
$email->set('parentId', $contact->id);
return true;
}
else {
$account = $this->entityManager->getRepository('Account')->where([
'emailAddress' => $emailAddress
])->findOne();
if ($account) {
$email->set('parentType', 'Account');
$email->set('parentId', $account->id);
return true;
} else {
$lead = $this->entityManager->getRepository('Lead')->where([
'emailAddress' => $emailAddress
])->findOne();
if ($lead) {
$email->set('parentType', 'Lead');
$email->set('parentId', $lead->id);
return true;
}
}
$account = $this->entityManager
->getRepository('Account')
->where([
'emailAddress' => $emailAddress
])
->findOne();
if ($account) {
$email->set('parentType', 'Account');
$email->set('parentId', $account->id);
return true;
}
$lead = $this->entityManager
->getRepository('Lead')
->where([
'emailAddress' => $emailAddress
])
->findOne();
if ($lead) {
$email->set('parentType', 'Lead');
$email->set('parentId', $lead->id);
return true;
}
return false;
}
protected function findDuplicate(Email $email) : ?Email
protected function findDuplicate(Email $email): ?Email
{
if (!$email->get('messageId')) {
return null;
}
$duplicate = $this->entityManager->getRepository('Email')
$duplicate = $this->entityManager
->getRepository('Email')
->select(['id', 'status'])
->where([
'messageId' => $email->get('messageId'),
@@ -498,15 +548,23 @@ class Importer
return $duplicate;
}
protected function processDuplicate(Email $duplicate, $assignedUserId, $userIdList, $folderData, $teamsIdList)
{
protected function processDuplicate(
Email $duplicate,
$assignedUserId,
$userIdList,
$folderData,
$teamsIdList
): void {
if ($duplicate->get('status') == 'Archived') {
$this->entityManager->getRepository('Email')->loadFromField($duplicate);
$this->entityManager->getRepository('Email')->loadToField($duplicate);
}
$duplicate->loadLinkMultipleField('users');
$fetchedUserIdList = $duplicate->getLinkMultipleIdList('users');
$duplicate->setLinkMultipleIdList('users', []);
$processNoteAcl = false;
@@ -514,8 +572,10 @@ class Importer
if ($assignedUserId) {
if (!in_array($assignedUserId, $fetchedUserIdList)) {
$processNoteAcl = true;
$duplicate->addLinkMultipleId('users', $assignedUserId);
}
$duplicate->addLinkMultipleId('assignedUsers', $assignedUserId);
}
@@ -523,6 +583,7 @@ class Importer
foreach ($userIdList as $uId) {
if (!in_array($uId, $fetchedUserIdList)) {
$processNoteAcl = true;
$duplicate->addLinkMultipleId('users', $uId);
}
}
@@ -532,29 +593,41 @@ class Importer
foreach ($folderData as $uId => $folderId) {
if (!in_array($uId, $fetchedUserIdList)) {
$duplicate->setLinkMultipleColumn('users', 'folderId', $uId, $folderId);
} else {
$this->entityManager->getRepository('Email')->updateRelation($duplicate, 'users', $uId, [
continue;
}
$this->entityManager
->getRepository('Email')
->updateRelation($duplicate, 'users', $uId, [
'folderId' => $folderId,
]);
}
}
}
$duplicate->set('isBeingImported', true);
$this->entityManager->getRepository('Email')->applyUsersFilters($duplicate);
$this->entityManager
->getRepository('Email')
->applyUsersFilters($duplicate);
$this->entityManager->getRepository('Email')->processLinkMultipleFieldSave($duplicate, 'users', [
'skipLinkMultipleRemove' => true,
'skipLinkMultipleUpdate' => true,
]);
$this->entityManager
->getRepository('Email')
->processLinkMultipleFieldSave($duplicate, 'users', [
'skipLinkMultipleRemove' => true,
'skipLinkMultipleUpdate' => true,
]);
$this->entityManager->getRepository('Email')->processLinkMultipleFieldSave($duplicate, 'assignedUsers', [
'skipLinkMultipleRemove' => true,
'skipLinkMultipleUpdate' => true,
]);
$this->entityManager
->getRepository('Email')
->processLinkMultipleFieldSave($duplicate, 'assignedUsers', [
'skipLinkMultipleRemove' => true,
'skipLinkMultipleUpdate' => true,
]);
if ($notificator = $this->notificator) {
$notificator = $this->notificator;
if ($notificator) {
$notificator->process($duplicate, [
'isBeingImported' => true,
]);
@@ -566,20 +639,27 @@ class Importer
foreach ($teamsIdList as $teamId) {
if (!in_array($teamId, $fetchedTeamIdList)) {
$processNoteAcl = true;
$this->entityManager->getRepository('Email')->relate($duplicate, 'teams', $teamId);
}
}
}
if ($duplicate->get('parentType') && $processNoteAcl) {
// Need to update acl fields (users and teams)
// of notes related to the duplicate email.
// To grant access to the user who received the email.
$dt = new DateTime();
$dt->modify('+5 seconds');
$executeAt = $dt->format('Y-m-d H:i:s');
$job = $this->entityManager->getEntity('Job');
$job->set([
'serviceName' => 'Note',
'serviceName' => 'Stream',
'methodName' => 'processNoteAclJob',
'data' => [
'targetType' => 'Email',
@@ -588,6 +668,7 @@ class Importer
'executeAt' => $executeAt,
'queue' => 'q1',
]);
$this->entityManager->saveEntity($job);
}
}
@@ -35,13 +35,20 @@ use Espo\Core\{
ServiceFactory,
};
/**
* Notes having `related` or `superParent` are subjects to access control
* through `users` and `teams` fields.
*
* When users or teams of `related` or `parent` record are changed
* the note record will be changed too.
*/
class StreamNotesAcl
{
protected $noteService = null;
private $streamService = null;
public static $order = 10;
protected $serviceFactory;
private $serviceFactory;
public function __construct(ServiceFactory $serviceFactory)
{
@@ -66,12 +73,12 @@ class StreamNotesAcl
return;
}
if (!$this->noteService) {
$this->noteService = $this->serviceFactory->create('Note');
if (!$this->streamService) {
$this->streamService = $this->serviceFactory->create('Stream');
}
$forceProcessNoteNotifications = !empty($options['forceProcessNoteNotifications']);
$this->noteService->processNoteAcl($entity, $forceProcessNoteNotifications);
$this->streamService->processNoteAcl($entity, $forceProcessNoteNotifications);
}
}
-185
View File
@@ -40,14 +40,10 @@ use Espo\Entities\Note as NoteEntity;
use Espo\ORM\Entity;
use DateTime;
use StdClass;
use Exception;
class Note extends Record
{
protected $noteNotificationPeriod = '1 hour';
public function loadAdditionalFields(Entity $entity)
{
parent::loadAdditionalFields($entity);
@@ -357,185 +353,4 @@ class Note extends Record
parent::unlink($id, $link, $foreignId);
}
public function processNoteAclJob(StdClass $data): void
{
$targetType = $data->targetType;
$targetId = $data->targetId;
if ($targetType && $targetId && $this->entityManager->hasRepository($targetType)) {
$entity = $this->entityManager->getEntity($targetType, $targetId);
if ($entity) {
$this->processNoteAcl($entity, true);
}
}
}
/**
* Changes users and teams of notes related to an entity according users and teams of the entity.
*/
public function processNoteAcl(Entity $entity, bool $forceProcessNoteNotifications = false): void
{
$entityType = $entity->getEntityType();
if (in_array($entityType, ['Note', 'User', 'Team', 'Role', 'Portal', 'PortalRole'])) {
return;
}
if (!$this->getMetadata()->get(['scopes', $entityType, 'acl'])) {
return;
}
if (!$this->getMetadata()->get(['scopes', $entityType, 'object'])) {
return;
}
$usersAttributeIsChanged = false;
$teamsAttributeIsChanged = false;
$ownerUserField = $this->getAclManager()->getReadOwnerUserField($entityType);
/* @var $defs \Espo\ORM\Defs\EntityDefs */
$defs = $this->entityManager->getDefs()->getEntity($entity->getEntityType());
$userIdList = [];
if ($ownerUserField) {
if (!$defs->hasField($ownerUserField)) {
throw new Error("Non-existing read-owner user field.");
}
$fieldDefs = $defs->getField($ownerUserField);
if ($fieldDefs->getType() === 'linkMultiple') {
$ownerUserIdAttribute = $ownerUserField . 'Ids';
}
else if ($fieldDefs->getType() === 'link') {
$ownerUserIdAttribute = $ownerUserField . 'Id';
}
else {
throw new Error("Bad read-owner user field type.");
}
if ($entity->isAttributeChanged($ownerUserIdAttribute)) {
$usersAttributeIsChanged = true;
}
if ($usersAttributeIsChanged || $forceProcessNoteNotifications) {
if ($fieldDefs->getType() === 'linkMultiple') {
$userIdList = $entity->getLinkMultipleIdList($ownerUserField);
}
else {
$userId = $entity->get($ownerUserIdAttribute);
$userIdList = $userId ? [$userId] : [];
}
}
}
if ($entity->hasLinkMultipleField('teams')) {
if ($entity->isAttributeChanged('teamsIds')) {
$teamsAttributeIsChanged = true;
}
if ($teamsAttributeIsChanged || $forceProcessNoteNotifications) {
$teamIdList = $entity->getLinkMultipleIdList('teams');
}
}
if (!$usersAttributeIsChanged && !$teamsAttributeIsChanged && !$forceProcessNoteNotifications) {
return;
}
$noteList = $this->entityManager
->getRepository('Note')
->where([
'OR' => [
[
'relatedId' => $entity->getId(),
'relatedType' => $entityType,
],
[
'parentId' => $entity->getId(),
'parentType' => $entityType,
'superParentId!=' => null,
'relatedId' => null,
]
]
])
->select([
'id',
'parentType',
'parentId',
'superParentType',
'superParentId',
'isInternal',
'relatedType',
'relatedId',
'createdAt',
])
->find();
$noteOptions = [];
if (!empty($forceProcessNoteNotifications)) {
$noteOptions['forceProcessNotifications'] = true;
}
$period = '-' . $this->getConfig()->get('noteNotificationPeriod', $this->noteNotificationPeriod);
$threshold = (new DateTime())->modify($period);
foreach ($noteList as $note) {
$this->processNoteAclItem($entity, $note, [
'teamsAttributeIsChanged' => $teamsAttributeIsChanged,
'usersAttributeIsChanged' => $usersAttributeIsChanged,
'forceProcessNoteNotifications' => $forceProcessNoteNotifications,
'teamIdList' => $teamIdList,
'userIdList' => $userIdList,
'threshold' => $threshold,
]);
}
}
protected function processNoteAclItem(Entity $entity, NoteEntity $note, array $params): void
{
$teamsAttributeIsChanged = $params['teamsAttributeIsChanged'];
$usersAttributeIsChanged = $params['usersAttributeIsChanged'];
$forceProcessNoteNotifications = $params['forceProcessNoteNotifications'];
$teamIdList = $params['teamIdList'];
$userIdList = $params['userIdList'];
$threshold = $params['threshold'];
$noteOptions = [
'forceProcessNotifications' => $forceProcessNoteNotifications,
];
if (!$entity->isNew() && $note->get('createdAt')) {
try {
$createdAtDt = new DateTime($note->get('createdAt'));
}
catch (Exception $e) {
return;
}
if ($createdAtDt->getTimestamp() < $threshold->getTimestamp()) {
return;
}
}
if ($teamsAttributeIsChanged || $forceProcessNoteNotifications) {
$note->set('teamsIds', $teamIdList);
}
if ($usersAttributeIsChanged || $forceProcessNoteNotifications) {
$note->set('usersIds', $userIdList);
}
$this->entityManager->saveEntity($note, $noteOptions);
}
}
+197
View File
@@ -40,6 +40,7 @@ use Espo\ORM\{
use Espo\{
Entities\User,
Entities\Note as NoteEntity,
Services\Notification as NotificationService,
};
@@ -58,6 +59,7 @@ use Espo\Core\{
};
use StdClass;
use DateTime;
class Stream
{
@@ -93,6 +95,8 @@ class Stream
protected $selectBuilderFactory;
protected const NOTE_ACL_PERIOD = '1 hour';
public function __construct(
EntityManager $entityManager,
Config $config,
@@ -1210,6 +1214,13 @@ class Stream
}
}
/**
* Notes having `related` or `superParent` are subjects to access control
* through `users` and `teams` fields.
*
* When users or teams of `related` or `parent` record are changed
* the note record will be changed too.
*/
protected function processNoteTeamsUsers(Entity $note, Entity $entity): void
{
$note->setAclIsProcessed();
@@ -2078,4 +2089,190 @@ class Stream
return $userList;
}
public function processNoteAclJob(StdClass $data): void
{
$targetType = $data->targetType;
$targetId = $data->targetId;
if ($targetType && $targetId && $this->entityManager->hasRepository($targetType)) {
$entity = $this->entityManager->getEntity($targetType, $targetId);
if ($entity) {
$this->processNoteAcl($entity, true);
}
}
}
/**
* Changes users and teams of notes related to an entity according users and teams of the entity.
*
* Notes having `related` or `superParent` are subjects to access control
* through `users` and `teams` fields.
*
* When users or teams of `related` or `parent` record are changed
* the note record will be changed too.
*/
public function processNoteAcl(Entity $entity, bool $forceProcessNoteNotifications = false): void
{
$entityType = $entity->getEntityType();
if (in_array($entityType, ['Note', 'User', 'Team', 'Role', 'Portal', 'PortalRole'])) {
return;
}
if (!$this->metadata->get(['scopes', $entityType, 'acl'])) {
return;
}
if (!$this->metadata->get(['scopes', $entityType, 'object'])) {
return;
}
$usersAttributeIsChanged = false;
$teamsAttributeIsChanged = false;
$ownerUserField = $this->aclManager->getReadOwnerUserField($entityType);
/* @var $defs \Espo\ORM\Defs\EntityDefs */
$defs = $this->entityManager->getDefs()->getEntity($entity->getEntityType());
$userIdList = [];
if ($ownerUserField) {
if (!$defs->hasField($ownerUserField)) {
throw new Error("Non-existing read-owner user field.");
}
$fieldDefs = $defs->getField($ownerUserField);
if ($fieldDefs->getType() === 'linkMultiple') {
$ownerUserIdAttribute = $ownerUserField . 'Ids';
}
else if ($fieldDefs->getType() === 'link') {
$ownerUserIdAttribute = $ownerUserField . 'Id';
}
else {
throw new Error("Bad read-owner user field type.");
}
if ($entity->isAttributeChanged($ownerUserIdAttribute)) {
$usersAttributeIsChanged = true;
}
if ($usersAttributeIsChanged || $forceProcessNoteNotifications) {
if ($fieldDefs->getType() === 'linkMultiple') {
$userIdList = $entity->getLinkMultipleIdList($ownerUserField);
}
else {
$userId = $entity->get($ownerUserIdAttribute);
$userIdList = $userId ? [$userId] : [];
}
}
}
if ($entity->hasLinkMultipleField('teams')) {
if ($entity->isAttributeChanged('teamsIds')) {
$teamsAttributeIsChanged = true;
}
if ($teamsAttributeIsChanged || $forceProcessNoteNotifications) {
$teamIdList = $entity->getLinkMultipleIdList('teams');
}
}
if (!$usersAttributeIsChanged && !$teamsAttributeIsChanged && !$forceProcessNoteNotifications) {
return;
}
$noteList = $this->entityManager
->getRepository('Note')
->where([
'OR' => [
[
'relatedId' => $entity->getId(),
'relatedType' => $entityType,
],
[
'parentId' => $entity->getId(),
'parentType' => $entityType,
'superParentId!=' => null,
'relatedId' => null,
]
]
])
->select([
'id',
'parentType',
'parentId',
'superParentType',
'superParentId',
'isInternal',
'relatedType',
'relatedId',
'createdAt',
])
->find();
$noteOptions = [];
if (!empty($forceProcessNoteNotifications)) {
$noteOptions['forceProcessNotifications'] = true;
}
$period = '-' . $this->config->get('noteNotificationPeriod', self::NOTE_ACL_PERIOD);
$threshold = (new DateTime())->modify($period);
foreach ($noteList as $note) {
$this->processNoteAclItem($entity, $note, [
'teamsAttributeIsChanged' => $teamsAttributeIsChanged,
'usersAttributeIsChanged' => $usersAttributeIsChanged,
'forceProcessNoteNotifications' => $forceProcessNoteNotifications,
'teamIdList' => $teamIdList,
'userIdList' => $userIdList,
'threshold' => $threshold,
]);
}
}
protected function processNoteAclItem(Entity $entity, NoteEntity $note, array $params): void
{
$teamsAttributeIsChanged = $params['teamsAttributeIsChanged'];
$usersAttributeIsChanged = $params['usersAttributeIsChanged'];
$forceProcessNoteNotifications = $params['forceProcessNoteNotifications'];
$teamIdList = $params['teamIdList'];
$userIdList = $params['userIdList'];
$threshold = $params['threshold'];
$noteOptions = [
'forceProcessNotifications' => $forceProcessNoteNotifications,
];
if (!$entity->isNew() && $note->get('createdAt')) {
try {
$createdAtDt = new DateTime($note->get('createdAt'));
}
catch (Exception $e) {
return;
}
if ($createdAtDt->getTimestamp() < $threshold->getTimestamp()) {
return;
}
}
if ($teamsAttributeIsChanged || $forceProcessNoteNotifications) {
$note->set('teamsIds', $teamIdList);
}
if ($usersAttributeIsChanged || $forceProcessNoteNotifications) {
$note->set('usersIds', $userIdList);
}
$this->entityManager->saveEntity($note, $noteOptions);
}
}
-4
View File
@@ -31,7 +31,6 @@ namespace tests\integration\Espo\Note;
use Espo\{
Services\Stream as StreamService,
Services\Note as NoteService,
ORM\EntityManager,
};
@@ -42,9 +41,6 @@ class AclTest extends \tests\integration\Core\BaseTestCase
/* @var $em EntityManager*/
$em = $this->getContainer()->get('entityManager');
/* @var $noteService NoteService*/
$noteService = $this->getContainer()->get('serviceFactory')->create('Note');
/* @var $streamService StreamService*/
$streamService = $this->getContainer()->get('serviceFactory')->create('Stream');