This commit is contained in:
Yuri Kuznetsov
2022-10-23 15:04:53 +03:00
parent 4374688c85
commit ee70b1afad
6 changed files with 86 additions and 106 deletions

View File

@@ -29,60 +29,62 @@
namespace Espo\Classes\AssignmentNotificators;
use Espo\Entities\EmailAddress;
use Espo\Entities\EmailFolder;
use Espo\Modules\Crm\Entities\Account;
use Espo\Modules\Crm\Entities\Contact;
use Espo\Modules\Crm\Entities\Lead;
use Espo\Tools\Stream\Service as StreamService;
use Espo\Core\Notification\AssignmentNotificator;
use Espo\Core\Notification\AssignmentNotificator\Params;
use Espo\Core\Notification\UserEnabledChecker;
use Espo\Core\InjectableFactory;
use Espo\Core\AclManager;
use Espo\ORM\EntityManager;
use Espo\ORM\Entity;
use Espo\Entities\User;
use Espo\Entities\Notification;
use Espo\Entities\Email as EmailEntity;
use Espo\Repositories\Email as EmailRepository;
use Espo\Repositories\EmailAddress as EmailAddressRepository;
use DateTime;
use Espo\Tools\Email\Util;
use DateTime;
use Exception;
/**
* @implements AssignmentNotificator<EmailEntity>
*/
class Email implements AssignmentNotificator
{
private const DAYS_THRESHOLD = 2;
private ?StreamService $streamService = null;
private $user;
private $entityManager;
private $injectableFactory;
private $aclManager;
private $userChecker;
private User $user;
private EntityManager $entityManager;
private UserEnabledChecker $userChecker;
private AclManager $aclManager;
private StreamService $streamService;
public function __construct(
User $user,
EntityManager $entityManager,
UserEnabledChecker $userChecker,
InjectableFactory $injectableFactory,
AclManager $aclManager
AclManager $aclManager,
StreamService $streamService
) {
$this->user = $user;
$this->entityManager = $entityManager;
$this->userChecker = $userChecker;
$this->injectableFactory = $injectableFactory;
$this->aclManager = $aclManager;
$this->streamService = $streamService;
}
/**
* @param EmailEntity $entity
*/
public function process(Entity $entity, Params $params): void
{
/** @var EmailEntity $entity */
if (
!in_array(
$entity->get('status'),
$entity->getStatus(),
[
EmailEntity::STATUS_ARCHIVED,
EmailEntity::STATUS_SENT,
@@ -141,13 +143,13 @@ class Email implements AssignmentNotificator
$data = [
'emailId' => $entity->getId(),
'emailName' => $entity->get('name'),
'emailName' => $entity->getSubject(),
];
/** @var EmailRepository $emailRepository */
$emailRepository = $this->entityManager->getRepository('Email');
$emailRepository = $this->entityManager->getRepository(EmailEntity::ENTITY_TYPE);
/** @var EmailAddressRepository $emailAddressRepository */
$emailAddressRepository = $this->entityManager->getRepository('EmailAddress');
$emailAddressRepository = $this->entityManager->getRepository(EmailAddress::ENTITY_TYPE);
if (!$entity->has('from')) {
$emailRepository->loadFromField($entity);
@@ -162,7 +164,11 @@ class Email implements AssignmentNotificator
$from = $entity->get('from');
if ($from) {
$person = $emailAddressRepository->getEntityByAddress($from, null, ['User', 'Contact', 'Lead']);
$person = $emailAddressRepository->getEntityByAddress($from, null, [
User::ENTITY_TYPE,
Contact::ENTITY_TYPE,
Lead::ENTITY_TYPE,
]);
if ($person) {
$data['personEntityType'] = $person->getEntityType();
@@ -187,8 +193,8 @@ class Email implements AssignmentNotificator
$parent = null;
$parentId = $entity->get('parentId');
$parentType = $entity->get('parentType');
$parentId = $entity->getParentId();
$parentType = $entity->getParentType();
if ($parentType && $parentId) {
$parent = $this->entityManager->getEntityById($parentType, $parentId);
@@ -196,10 +202,10 @@ class Email implements AssignmentNotificator
$account = null;
$accountId = $entity->get('accountId');
$accountLink = $entity->getAccount();
if ($accountId) {
$account = $this->entityManager->getEntityById('Account', $accountId);
if ($accountLink) {
$account = $this->entityManager->getEntityById(Account::ENTITY_TYPE, $accountLink->getId());
}
foreach ($userIdList as $userId) {
@@ -215,7 +221,7 @@ class Email implements AssignmentNotificator
continue;
}
if (!$this->userChecker->checkAssignment('Email', $userId)) {
if (!$this->userChecker->checkAssignment(EmailEntity::ENTITY_TYPE, $userId)) {
continue;
}
@@ -228,7 +234,7 @@ class Email implements AssignmentNotificator
if ($folderId) {
if (
$this->entityManager
->getRDBRepository('EmailFolder')
->getRDBRepositoryByClass(EmailFolder::class)
->where([
'id' => $folderId,
'skipNotifications' => true,
@@ -241,7 +247,7 @@ class Email implements AssignmentNotificator
}
/** @var User|null $user */
$user = $this->entityManager->getEntity('User', $userId);
$user = $this->entityManager->getEntityById(EmailEntity::ENTITY_TYPE, $userId);
if (!$user) {
continue;
@@ -251,18 +257,18 @@ class Email implements AssignmentNotificator
continue;
}
if (!$this->aclManager->checkScope($user, 'Email')) {
if (!$this->aclManager->checkScope($user, EmailEntity::ENTITY_TYPE)) {
continue;
}
$isArchivedOrBeingImported =
$entity->get('status') === EmailEntity::STATUS_ARCHIVED ||
$entity->getStatus() === EmailEntity::STATUS_ARCHIVED ||
$params->getOption('isBeingImported');
if (
$isArchivedOrBeingImported &&
$parent &&
$this->getStreamService()->checkIsFollowed($parent, $userId)
$this->streamService->checkIsFollowed($parent, $userId)
) {
continue;
}
@@ -270,7 +276,7 @@ class Email implements AssignmentNotificator
if (
$isArchivedOrBeingImported &&
$account &&
$this->getStreamService()->checkIsFollowed($account, $userId)
$this->streamService->checkIsFollowed($account, $userId)
) {
continue;
}
@@ -281,7 +287,7 @@ class Email implements AssignmentNotificator
'type' => Notification::TYPE_EMAIL_RECEIVED,
'userId' => $userId,
'relatedId' => $entity->getId(),
'relatedType' => 'Email',
'relatedType' => EmailEntity::ENTITY_TYPE,
])
->select(['id'])
->findOne();
@@ -295,17 +301,8 @@ class Email implements AssignmentNotificator
'userId' => $userId,
'data' => $data,
'relatedId' => $entity->getId(),
'relatedType' => 'Email',
'relatedType' => EmailEntity::ENTITY_TYPE,
]);
}
}
private function getStreamService(): StreamService
{
if (empty($this->streamService)) {
$this->streamService = $this->injectableFactory->create(StreamService::class);
}
return $this->streamService;
}
}

View File

@@ -70,6 +70,7 @@ class Importer
private EntityManager $entityManager;
private Config $config;
/** @var AssignmentNotificator<Email> */
private AssignmentNotificator $notificator;
private FiltersMatcher $filtersMatcher;
private ParserFactory $parserFactory;
@@ -93,7 +94,7 @@ class Importer
$this->duplicateFinder = $duplicateFinder;
$this->jobSchedulerFactory = $jobSchedulerFactory;
$this->notificator = $notificatorFactory->create(Email::ENTITY_TYPE);
$this->notificator = $notificatorFactory->createByClass(Email::class);
$this->filtersMatcher = new FiltersMatcher();
}

View File

@@ -30,11 +30,12 @@
namespace Espo\Core\Notification;
use Espo\ORM\Entity;
use Espo\Core\Notification\AssignmentNotificator\Params;
/**
* Processes assignment notifications. Called after entity is saved.
*
* @template TEntity of Entity
*/
interface AssignmentNotificator
{

View File

@@ -29,25 +29,19 @@
namespace Espo\Core\Notification;
use Espo\Core\{
InjectableFactory,
Utils\ClassFinder,
Utils\Metadata,
Notification\DefaultAssignmentNotificator,
Notification\AssignmentNotificator,
};
use Espo\Core\InjectableFactory;
use Espo\Core\Utils\ClassFinder;
use Espo\Core\Utils\Metadata;
use Espo\ORM\Entity;
use Espo\ORM\Repository\Util as RepositoryUtil;
class AssignmentNotificatorFactory
{
/**
* @var class-string<AssignmentNotificator>
*/
/** @var class-string<AssignmentNotificator<Entity>> */
protected string $defaultClassName = DefaultAssignmentNotificator::class;
private InjectableFactory $injectableFactory;
private ClassFinder $classFinder;
private Metadata $metadata;
public function __construct(InjectableFactory $injectableFactory, ClassFinder $classFinder, Metadata $metadata)
@@ -57,10 +51,23 @@ class AssignmentNotificatorFactory
$this->metadata = $metadata;
}
/**
* @template T of Entity
* @param class-string<T> $className An entity class name.
* @return AssignmentNotificator<T>
*/
public function createByClass(string $className): AssignmentNotificator
{
$entityType = RepositoryUtil::getEntityTypeByClass($className);
/** @var AssignmentNotificator<T> */
return $this->create($entityType);
}
/**
* @todo Change return type to AssignmentNotificator.
*
* @return AssignmentNotificator
* @return AssignmentNotificator<Entity>
*/
public function create(string $entityType): object // AssignmentNotificator
{
@@ -70,11 +77,11 @@ class AssignmentNotificatorFactory
}
/**
* @return class-string<AssignmentNotificator>
* @return class-string<AssignmentNotificator<Entity>>
*/
private function getClassName(string $entityType): string
{
/** @var ?class-string<AssignmentNotificator> $className1 */
/** @var ?class-string<AssignmentNotificator<Entity>> $className1 */
$className1 = $this->metadata->get(['notificationDefs', $entityType, 'assignmentNotificatorClassName']);
if ($className1) {
@@ -82,7 +89,7 @@ class AssignmentNotificatorFactory
}
/* For backward compatibility. */
/** @var ?class-string<AssignmentNotificator> $className2 */
/** @var ?class-string<AssignmentNotificator<Entity>> $className2 */
$className2 = $this->classFinder->find('Notificators', $entityType);
if ($className2) {

View File

@@ -30,31 +30,20 @@
namespace Espo\Core\Notification;
use Espo\Core\ORM\Entity as CoreEntity;
use Espo\ORM\Entity;
use Espo\ORM\EntityManager;
use Espo\Entities\User;
use Espo\Entities\Notification;
use Espo\Core\Notification\AssignmentNotificator\Params;
/**
* @implements AssignmentNotificator<Entity>
*/
class DefaultAssignmentNotificator implements AssignmentNotificator
{
/**
* @var User
*/
protected $user;
/**
* @var EntityManager
*/
protected $entityManager;
/**
* @var UserEnabledChecker
*/
protected $userChecker;
protected User $user;
protected EntityManager $entityManager;
protected UserEnabledChecker $userChecker;
public function __construct(User $user, EntityManager $entityManager, UserEnabledChecker $userChecker)
{

View File

@@ -32,18 +32,13 @@ namespace Espo\Tools\Notification;
use Espo\Core\Notification\AssignmentNotificatorFactory;
use Espo\Core\Notification\AssignmentNotificator;
use Espo\Core\Notification\AssignmentNotificator\Params as AssignmentNotificatorParams;
use Espo\Core\Utils\Metadata;
use Espo\Core\Utils\Config;
use Espo\Tools\Stream\Service as StreamService;
use Espo\ORM\EntityManager;
use Espo\ORM\Entity;
use Espo\Entities\User;
use Espo\Entities\Notification;
use Espo\Core\ORM\Entity as CoreEntity;
/**
@@ -51,30 +46,20 @@ use Espo\Core\ORM\Entity as CoreEntity;
*/
class HookProcessor
{
/**
* @var array<string,AssignmentNotificator>
*/
private $notifatorsHash = [];
/**
* @var array<string,bool>
*/
/** @var array<string, AssignmentNotificator<Entity>> */
private $notificatorsHash = [];
/** @var array<string,bool> */
private $hasStreamCache = [];
/** @var array<string,string> */
private $userNameHash = [];
private Metadata $metadata;
private Config $config;
private EntityManager $entityManager;
private StreamService $streamService;
private AssignmentNotificatorFactory $notificatorFactory;
private User $user;
/**
* @var array<string,string>
*/
private $userNameHash = [];
public function __construct(
Metadata $metadata,
Config $config,
@@ -201,17 +186,17 @@ class HookProcessor
}
/**
* @return AssignmentNotificator
* @return AssignmentNotificator<Entity>
*/
private function getNotificator(string $entityType): object
{
if (empty($this->notifatorsHash[$entityType])) {
if (empty($this->notificatorsHash[$entityType])) {
$notificator = $this->notificatorFactory->create($entityType);
$this->notifatorsHash[$entityType] = $notificator;
$this->notificatorsHash[$entityType] = $notificator;
}
return $this->notifatorsHash[$entityType];
return $this->notificatorsHash[$entityType];
}
private function getUserNameById(string $id): string
@@ -221,7 +206,7 @@ class HookProcessor
}
if (!array_key_exists($id, $this->userNameHash)) {
/** @var User|null $user */
/** @var ?User $user */
$user = $this->entityManager->getEntityById(User::ENTITY_TYPE, $id);
if ($user) {