diff --git a/app/code/Magento/Newsletter/Model/CustomerSubscriberCache.php b/app/code/Magento/Newsletter/Model/CustomerSubscriberCache.php new file mode 100644 index 0000000000000..37abccea93b87 --- /dev/null +++ b/app/code/Magento/Newsletter/Model/CustomerSubscriberCache.php @@ -0,0 +1,46 @@ +customerSubscriber[$customerId])) { + $subscriber = $this->customerSubscriber[$customerId]; + } + + return $subscriber; + } + + /** + * Set Subscriber to cache by Customer id. + * + * @param int $customerId + * @param Subscriber|null $subscriber + */ + public function setCustomerSubscriber(int $customerId, ?Subscriber $subscriber): void + { + $this->customerSubscriber[$customerId] = $subscriber; + } +} diff --git a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php index b532e9787b66c..7ec94ee5bc101 100644 --- a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php +++ b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php @@ -3,21 +3,24 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Newsletter\Model\Plugin; use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Api\Data\CustomerExtensionInterface; use Magento\Customer\Api\Data\CustomerInterface; use Magento\Customer\Model\Config\Share; use Magento\Framework\Api\ExtensionAttributesFactory; +use Magento\Framework\Api\SearchResults; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Newsletter\Model\Subscriber; +use Magento\Newsletter\Model\CustomerSubscriberCache; use Magento\Newsletter\Model\ResourceModel\Subscriber\CollectionFactory; -use Magento\Customer\Api\Data\CustomerExtensionInterface; +use Magento\Newsletter\Model\Subscriber; use Magento\Newsletter\Model\SubscriberFactory; use Magento\Newsletter\Model\SubscriptionManagerInterface; use Magento\Store\Model\Store; use Magento\Store\Model\StoreManagerInterface; -use Magento\Framework\Api\SearchResults; use Psr\Log\LoggerInterface; /** @@ -62,6 +65,11 @@ class CustomerPlugin */ private $logger; + /** + * @var CustomerSubscriberCache + */ + private $customerSubscriberCache; + /** * @param SubscriberFactory $subscriberFactory * @param ExtensionAttributesFactory $extensionFactory @@ -70,6 +78,7 @@ class CustomerPlugin * @param Share $shareConfig * @param StoreManagerInterface $storeManager * @param LoggerInterface $logger + * @param CustomerSubscriberCache|null $customerSubscriberCache */ public function __construct( SubscriberFactory $subscriberFactory, @@ -78,7 +87,8 @@ public function __construct( SubscriptionManagerInterface $subscriptionManager, Share $shareConfig, StoreManagerInterface $storeManager, - LoggerInterface $logger + LoggerInterface $logger, + CustomerSubscriberCache $customerSubscriberCache = null ) { $this->subscriberFactory = $subscriberFactory; $this->extensionFactory = $extensionFactory; @@ -87,6 +97,8 @@ public function __construct( $this->shareConfig = $shareConfig; $this->storeManager = $storeManager; $this->logger = $logger; + $this->customerSubscriberCache = $customerSubscriberCache + ?? ObjectManager::getInstance()->get(CustomerSubscriberCache::class); } /** @@ -124,9 +136,11 @@ public function afterSave( } if ($needToUpdate) { $storeId = $this->getCurrentStoreId($result); + $customerId = (int)$result->getId(); $subscriber = $subscribeStatus - ? $this->subscriptionManager->subscribeCustomer((int)$result->getId(), $storeId) - : $this->subscriptionManager->unsubscribeCustomer((int)$result->getId(), $storeId); + ? $this->subscriptionManager->subscribeCustomer($customerId, $storeId) + : $this->subscriptionManager->unsubscribeCustomer($customerId, $storeId); + $this->customerSubscriberCache->setCustomerSubscriber($customerId, $subscriber); } $this->addIsSubscribedExtensionAttribute($result, $subscriber->isSubscribed()); @@ -252,7 +266,7 @@ public function afterGetList(CustomerRepositoryInterface $subject, SearchResults $extensionAttributes = $customer->getExtensionAttributes(); /** @var Subscriber $subscribe */ $subscribe = $collection->getItemByColumnValue('subscriber_email', $customer->getEmail()); - $isSubscribed = $subscribe && (int) $subscribe->getStatus() === Subscriber::STATUS_SUBSCRIBED; + $isSubscribed = $subscribe && (int)$subscribe->getStatus() === Subscriber::STATUS_SUBSCRIBED; $extensionAttributes->setIsSubscribed($isSubscribed); } @@ -308,16 +322,20 @@ private function deleteSubscriptionsAfterCustomerDelete(CustomerInterface $custo */ private function getSubscriber(CustomerInterface $customer): Subscriber { - /** @var Subscriber $subscriber */ - $subscriber = $this->subscriberFactory->create(); - $websiteId = $this->getCurrentWebsiteId($customer); - $subscriber->loadByCustomer((int)$customer->getId(), $websiteId); - /** - * If subscriber was't found by customer id then try to find subscriber by customer email. - * It need when the customer is creating and he has already subscribed as guest by same email. - */ - if (!$subscriber->getId()) { - $subscriber->loadBySubscriberEmail((string)$customer->getEmail(), $websiteId); + $customerId = (int)$customer->getId(); + $subscriber = $this->customerSubscriberCache->getCustomerSubscriber($customerId); + if ($subscriber === null) { + $subscriber = $this->subscriberFactory->create(); + $websiteId = $this->getCurrentWebsiteId($customer); + $subscriber->loadByCustomer((int)$customer->getId(), $websiteId); + /** + * If subscriber wasn't found by customer id then try to find subscriber by customer email. + * It need when the customer is creating and he has already subscribed as guest by same email. + */ + if (!$subscriber->getId()) { + $subscriber->loadBySubscriberEmail((string)$customer->getEmail(), $websiteId); + } + $this->customerSubscriberCache->setCustomerSubscriber($customerId, $subscriber); } return $subscriber; diff --git a/app/code/Magento/Newsletter/Model/SubscriptionManager.php b/app/code/Magento/Newsletter/Model/SubscriptionManager.php index 57c6cd8b843a7..05be8325e3243 100644 --- a/app/code/Magento/Newsletter/Model/SubscriptionManager.php +++ b/app/code/Magento/Newsletter/Model/SubscriptionManager.php @@ -11,6 +11,7 @@ use Magento\Customer\Api\CustomerRepositoryInterface; use Magento\Customer\Api\Data\CustomerInterface; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\MailException; use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; @@ -51,6 +52,11 @@ class SubscriptionManager implements SubscriptionManagerInterface */ private $customerRepository; + /** + * @var CustomerSubscriberCache + */ + private $customerSubscriberCache; + /** * @param SubscriberFactory $subscriberFactory * @param LoggerInterface $logger @@ -58,6 +64,7 @@ class SubscriptionManager implements SubscriptionManagerInterface * @param ScopeConfigInterface $scopeConfig * @param AccountManagementInterface $customerAccountManagement * @param CustomerRepositoryInterface $customerRepository + * @param CustomerSubscriberCache|null $customerSubscriberCache */ public function __construct( SubscriberFactory $subscriberFactory, @@ -65,7 +72,8 @@ public function __construct( StoreManagerInterface $storeManager, ScopeConfigInterface $scopeConfig, AccountManagementInterface $customerAccountManagement, - CustomerRepositoryInterface $customerRepository + CustomerRepositoryInterface $customerRepository, + CustomerSubscriberCache $customerSubscriberCache = null ) { $this->subscriberFactory = $subscriberFactory; $this->logger = $logger; @@ -73,6 +81,8 @@ public function __construct( $this->scopeConfig = $scopeConfig; $this->customerAccountManagement = $customerAccountManagement; $this->customerRepository = $customerRepository; + $this->customerSubscriberCache = $customerSubscriberCache + ?? ObjectManager::getInstance()->get(CustomerSubscriberCache::class); } /** @@ -209,14 +219,16 @@ private function saveSubscriber( if (!$subscriber->getId()) { $subscriber->setSubscriberConfirmCode($subscriber->randomSequence()); } + $customerId = (int)$customer->getId(); $subscriber->setStatus($status) ->setStatusChanged($statusChanged) - ->setCustomerId($customer->getId()) + ->setCustomerId($customerId) ->setStoreId($storeId) ->setEmail($customer->getEmail()) ->save(); if ($statusChanged) { + $this->customerSubscriberCache->setCustomerSubscriber($customerId, null); return true; }