diff --git a/application/Espo/Classes/AssignmentNotificators/Email.php b/application/Espo/Classes/AssignmentNotificators/Email.php index fa4b2aa1b5..4418d1fd98 100644 --- a/application/Espo/Classes/AssignmentNotificators/Email.php +++ b/application/Espo/Classes/AssignmentNotificators/Email.php @@ -39,6 +39,7 @@ use Espo\{ use Espo\Core\{ Notification\AssignmentNotificator, Notification\UserEnabledChecker, + Notification\NotificatorParams, ORM\EntityManager, ServiceFactory, AclManager, @@ -77,13 +78,13 @@ class Email implements AssignmentNotificator $this->aclManager = $aclManager; } - public function process(Entity $entity, array $options = []) : void + public function process(Entity $entity, NotificatorParams $params) : void { if (!in_array($entity->get('status'), ['Archived', 'Sent', 'Being Imported'])) { return; } - if (!empty($options['isJustSent'])) { + if ($params->getOption('isJustSent')) { $previousUserIdList = []; } else { @@ -205,7 +206,10 @@ class Email implements AssignmentNotificator continue; } - if (!empty($options['isBeingImported']) || !empty($options['isJustSent'])) { + if ( + $params->getOption('isBeingImported') || + $params->getOption('isJustSent') + ) { $folderId = $entity->getLinkMultipleColumn('users', 'folderId', $userId); if ($folderId) { @@ -237,7 +241,10 @@ class Email implements AssignmentNotificator continue; } - if ($entity->get('status') == 'Archived' || !empty($options['isBeingImported'])) { + if ( + $entity->get('status') == 'Archived' || + $params->getOption('isBeingImported') + ) { if ($parent) { if ($this->getStreamService()->checkIsFollowed($parent, $userId)) { continue; diff --git a/application/Espo/Core/FieldProcessing/Relation/LinkMultipleSaver.php b/application/Espo/Core/FieldProcessing/Relation/LinkMultipleSaver.php index db357d3a49..fbb7312af8 100644 --- a/application/Espo/Core/FieldProcessing/Relation/LinkMultipleSaver.php +++ b/application/Espo/Core/FieldProcessing/Relation/LinkMultipleSaver.php @@ -33,6 +33,7 @@ use Espo\ORM\Entity; use Espo\Core\{ ORM\EntityManager, + FieldProcessing\SaverParams, }; class LinkMultipleSaver @@ -44,7 +45,7 @@ class LinkMultipleSaver $this->entityManager = $entityManager; } - public function process(Entity $entity, string $name, array $options): void + public function process(Entity $entity, string $name, SaverParams $params): void { $entityType = $entity->getEntityType(); @@ -55,9 +56,9 @@ class LinkMultipleSaver $defs = $this->entityManager->getDefs()->getEntity($entityType); - $skipCreate = $options['skipLinkMultipleCreate'] ?? false; - $skipRemove = $options['skipLinkMultipleRemove'] ?? false; - $skipUpdate = $options['skipLinkMultipleUpdate'] ?? false; + $skipCreate = $params->getOption('skipLinkMultipleCreate') ?? false; + $skipRemove = $params->getOption('skipLinkMultipleRemove') ?? false; + $skipUpdate = $params->getOption('skipLinkMultipleUpdate') ?? false; if ($entity->isNew()) { $skipRemove = true; @@ -156,11 +157,9 @@ class LinkMultipleSaver } if ( - property_exists($columnData->$id, $columnName) - && + property_exists($columnData->$id, $columnName) && ( - !property_exists($existingColumnsData->$id, $columnName) - || + !property_exists($existingColumnsData->$id, $columnName) || $columnData->$id->$columnName !== $existingColumnsData->$id->$columnName ) ) { diff --git a/application/Espo/Core/FieldProcessing/Relation/Saver.php b/application/Espo/Core/FieldProcessing/Relation/Saver.php index 5d77ad5f3b..9cb1329ad7 100644 --- a/application/Espo/Core/FieldProcessing/Relation/Saver.php +++ b/application/Espo/Core/FieldProcessing/Relation/Saver.php @@ -59,23 +59,21 @@ class Saver implements SaverInterface public function process(Entity $entity, SaverParams $params): void { - $options = $params->getRawOptions(); - - $this->processMany($entity, $options); - $this->processHasOne($entity, $options); - $this->processBelongsToHasOne($entity, $options); + $this->processMany($entity, $params); + $this->processHasOne($entity); + $this->processBelongsToHasOne($entity); } - private function processMany(Entity $entity, array $options): void + private function processMany(Entity $entity, SaverParams $params): void { $entityType = $entity->getEntityType(); foreach ($this->getManyRelationList($entityType) as $name) { - $this->processManyItem($entity, $name, $options); + $this->processManyItem($entity, $name, $params); } } - private function processManyItem(Entity $entity, string $name, array $options): void + private function processManyItem(Entity $entity, string $name, SaverParams $params): void { $idListAttribute = $name . 'Ids'; $columnsAttribute = $name . 'Columns'; @@ -84,10 +82,10 @@ class Saver implements SaverInterface return; } - $this->linkMultipleSaver->process($entity, $name, $options); + $this->linkMultipleSaver->process($entity, $name, $params); } - private function processHasOne(Entity $entity, array $options): void + private function processHasOne(Entity $entity): void { $entityType = $entity->getEntityType(); @@ -148,7 +146,7 @@ class Saver implements SaverInterface } } - private function processBelongsToHasOne(Entity $entity, array $options): void + private function processBelongsToHasOne(Entity $entity): void { $entityType = $entity->getEntityType(); diff --git a/application/Espo/Core/Mail/Importer.php b/application/Espo/Core/Mail/Importer.php index 7184fea036..a5e07ddd20 100644 --- a/application/Espo/Core/Mail/Importer.php +++ b/application/Espo/Core/Mail/Importer.php @@ -37,6 +37,7 @@ use Espo\Core\{ Utils\Config, Notification\AssignmentNotificator, Notification\AssignmentNotificatorFactory, + Notification\NotificatorParams, FieldProcessing\Relation\LinkMultipleSaver, FieldProcessing\SaverParams, }; @@ -620,10 +621,12 @@ class Importer $this->linkMultipleSaver->process($duplicate, 'users', $saverParams); $this->linkMultipleSaver->process($duplicate, 'assignedUsers', $saverParams); - $this->notificator->process($duplicate, [ + $notificatorParams = NotificatorParams::create()->withRawOptions([ 'isBeingImported' => true, ]); + $this->notificator->process($duplicate, $notificatorParams); + $fetchedTeamIdList = $duplicate->getLinkMultipleIdList('teams'); if (!empty($teamsIdList)) { diff --git a/application/Espo/Core/Notification/AssignmentNotificator.php b/application/Espo/Core/Notification/AssignmentNotificator.php index 5c08fe6403..6fc21b4735 100644 --- a/application/Espo/Core/Notification/AssignmentNotificator.php +++ b/application/Espo/Core/Notification/AssignmentNotificator.php @@ -36,5 +36,5 @@ use Espo\ORM\Entity; */ interface AssignmentNotificator { - public function process(Entity $entity, array $options = []): void; + public function process(Entity $entity, NotificatorParams $params): void; } diff --git a/application/Espo/Core/Notification/DefaultAssignmentNotificator.php b/application/Espo/Core/Notification/DefaultAssignmentNotificator.php index 09d77901dd..b49ca916a9 100644 --- a/application/Espo/Core/Notification/DefaultAssignmentNotificator.php +++ b/application/Espo/Core/Notification/DefaultAssignmentNotificator.php @@ -52,7 +52,7 @@ class DefaultAssignmentNotificator implements AssignmentNotificator $this->userChecker = $userChecker; } - public function process(Entity $entity, array $options = []): void + public function process(Entity $entity, NotificatorParams $params): void { if ($entity->hasLinkMultipleField('assignedUsers')) { $userIdList = $entity->getLinkMultipleIdList('assignedUsers'); diff --git a/application/Espo/Core/Notification/NotificatorParams.php b/application/Espo/Core/Notification/NotificatorParams.php new file mode 100644 index 0000000000..be46689ae7 --- /dev/null +++ b/application/Espo/Core/Notification/NotificatorParams.php @@ -0,0 +1,67 @@ +options); + } + + /** + * @return mixed + */ + public function getOption(string $option) + { + return $this->options[$option] ?? null; + } + + public function getRawOptions(): array + { + return $this->options; + } + + public function withRawOptions(array $options): self + { + $obj = clone $this; + + $obj->options = $options; + + return $obj; + } + + public static function create(): self + { + return new self(); + } +} diff --git a/application/Espo/Hooks/Common/Notifications.php b/application/Espo/Hooks/Common/Notifications.php index f039a6951c..9bb3ce806f 100644 --- a/application/Espo/Hooks/Common/Notifications.php +++ b/application/Espo/Hooks/Common/Notifications.php @@ -41,6 +41,7 @@ use Espo\Core\{ ServiceFactory, Notification\AssignmentNotificator, Notification\AssignmentNotificatorFactory, + Notification\NotificatorParams, }; use Espo\Entities\User; @@ -83,7 +84,7 @@ class Notifications $this->user = $user; } - public function afterSave(Entity $entity, array $options = []) : void + public function afterSave(Entity $entity, array $options = []): void { if (!empty($options['silent']) || !empty($options['noNotifications'])) { return; @@ -107,10 +108,19 @@ class Notifications $notificator = $this->getNotificator($entityType); - $notificator->process($entity, $options); + if (!$notificator instanceof AssignmentNotificator) { + // For backward compatiblity. + $notificator->process($entity, $options); + + return; + } + + $params = NotificatorParams::create()->withRawOptions($options); + + $notificator->process($entity, $params); } - public function beforeRemove(Entity $entity, array $options = []) : void + public function beforeRemove(Entity $entity, array $options = []): void { if (!empty($options['silent']) || !empty($options['noNotifications'])) { return; @@ -145,7 +155,7 @@ class Notifications } } - public function afterRemove(Entity $entity) : void + public function afterRemove(Entity $entity): void { $query = $this->entityManager->getQueryBuilder() ->delete() @@ -167,7 +177,7 @@ class Notifications $this->entityManager->getQueryExecutor()->execute($query); } - private function checkHasStream($entityType) : bool + private function checkHasStream($entityType): bool { if (!array_key_exists($entityType, $this->hasStreamCache)) { $this->hasStreamCache[$entityType] = (bool) $this->metadata->get("scopes.{$entityType}.stream"); @@ -179,7 +189,7 @@ class Notifications /** * @return AssignmentNotificator */ - private function getNotificator($entityType) : object + private function getNotificator(string $entityType): object { if (empty($this->notifatorsHash[$entityType])) { $notificator = $this->notificatorFactory->create($entityType); @@ -190,7 +200,7 @@ class Notifications return $this->notifatorsHash[$entityType]; } - private function getStreamService() : StreamService + private function getStreamService(): StreamService { if (empty($this->streamService)) { $this->streamService = $this->serviceFactory->create('Stream'); diff --git a/tests/unit/Espo/Core/Notification/NotificatorParamsTest.php b/tests/unit/Espo/Core/Notification/NotificatorParamsTest.php new file mode 100644 index 0000000000..cc595b3e8d --- /dev/null +++ b/tests/unit/Espo/Core/Notification/NotificatorParamsTest.php @@ -0,0 +1,55 @@ + true, + ]; + + $params = NotificatorParams + ::create() + ->withRawOptions($options); + + $this->assertEquals(true, $params->getOption('silent')); + $this->assertEquals(true, $params->hasOption('silent')); + $this->assertEquals(null, $params->getOption('skipHooks')); + $this->assertEquals(false, $params->hasOption('skipHooks')); + + $this->assertEquals($options, $params->getRawOptions()); + } +}