![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/module-newsletter/Model/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\Newsletter\Model; use Magento\Customer\Api\AccountManagementInterface; 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; use Psr\Log\LoggerInterface; /** * Class to update newsletter subscription status */ class SubscriptionManager implements SubscriptionManagerInterface { /** * @var SubscriberFactory */ private $subscriberFactory; /** * @var LoggerInterface */ private $logger; /** * @var StoreManagerInterface */ private $storeManager; /** * @var ScopeConfigInterface */ private $scopeConfig; /** * @var AccountManagementInterface */ private $customerAccountManagement; /** * @var CustomerRepositoryInterface */ private $customerRepository; /** * @var CustomerSubscriberCache */ private $customerSubscriberCache; /** * @param SubscriberFactory $subscriberFactory * @param LoggerInterface $logger * @param StoreManagerInterface $storeManager * @param ScopeConfigInterface $scopeConfig * @param AccountManagementInterface $customerAccountManagement * @param CustomerRepositoryInterface $customerRepository * @param CustomerSubscriberCache|null $customerSubscriberCache */ public function __construct( SubscriberFactory $subscriberFactory, LoggerInterface $logger, StoreManagerInterface $storeManager, ScopeConfigInterface $scopeConfig, AccountManagementInterface $customerAccountManagement, CustomerRepositoryInterface $customerRepository, CustomerSubscriberCache $customerSubscriberCache = null ) { $this->subscriberFactory = $subscriberFactory; $this->logger = $logger; $this->storeManager = $storeManager; $this->scopeConfig = $scopeConfig; $this->customerAccountManagement = $customerAccountManagement; $this->customerRepository = $customerRepository; $this->customerSubscriberCache = $customerSubscriberCache ?? ObjectManager::getInstance()->get(CustomerSubscriberCache::class); } /** * @inheritdoc */ public function subscribe(string $email, int $storeId): Subscriber { $websiteId = (int)$this->storeManager->getStore($storeId)->getWebsiteId(); $subscriber = $this->subscriberFactory->create()->loadBySubscriberEmail($email, $websiteId); $currentStatus = (int)$subscriber->getStatus(); if ($currentStatus === Subscriber::STATUS_SUBSCRIBED) { return $subscriber; } $status = $this->isConfirmNeed($storeId) ? Subscriber::STATUS_NOT_ACTIVE : Subscriber::STATUS_SUBSCRIBED; if (!$subscriber->getId()) { $subscriber->setSubscriberConfirmCode($subscriber->randomSequence()); $subscriber->setSubscriberEmail($email); } $subscriber->setStatus($status) ->setStoreId($storeId) ->save(); $this->sendEmailAfterChangeStatus($subscriber); return $subscriber; } /** * @inheritdoc */ public function unsubscribe(string $email, int $storeId, string $confirmCode): Subscriber { $websiteId = (int)$this->storeManager->getStore($storeId)->getWebsiteId(); /** @var Subscriber $subscriber */ $subscriber = $this->subscriberFactory->create()->loadBySubscriberEmail($email, $websiteId); if (!$subscriber->getId()) { return $subscriber; } $subscriber->setCheckCode($confirmCode); $subscriber->unsubscribe(); return $subscriber; } /** * @inheritdoc */ public function subscribeCustomer(int $customerId, int $storeId): Subscriber { return $this->updateCustomerSubscription($customerId, $storeId, true); } /** * @inheritdoc */ public function unsubscribeCustomer(int $customerId, int $storeId): Subscriber { return $this->updateCustomerSubscription($customerId, $storeId, false); } /** * Update customer newsletter subscription * * @param int $customerId * @param int $storeId * @param bool $status * @return Subscriber */ private function updateCustomerSubscription(int $customerId, int $storeId, bool $status): Subscriber { $customer = $this->customerRepository->getById($customerId); $websiteId = (int)$this->storeManager->getStore($storeId)->getWebsiteId(); $subscriber = $this->loadSubscriberByCustomer($customer, $websiteId); if (!$status && !$subscriber->getId()) { return $subscriber; } $newStatus = $this->getNewSubscriptionStatus($subscriber, $customer, $storeId, $status); $needToSendLetter = $this->saveSubscriber($subscriber, $customer, $storeId, $newStatus); if ($needToSendLetter) { $this->sendEmailAfterChangeStatus($subscriber); } return $subscriber; } /** * Load subscriber model by customer * * @param CustomerInterface $customer * @param int $websiteId * @return Subscriber */ private function loadSubscriberByCustomer(CustomerInterface $customer, int $websiteId): Subscriber { $subscriber = $this->subscriberFactory->create(); $subscriber->loadByCustomer((int)$customer->getId(), $websiteId); if (!$subscriber->getId()) { $subscriber->loadBySubscriberEmail((string)$customer->getEmail(), $websiteId); } return $subscriber; } /** * Save Subscriber model * * @param Subscriber $subscriber * @param CustomerInterface $customer * @param int $storeId * @param int $status * @return bool Need to send email */ private function saveSubscriber( Subscriber $subscriber, CustomerInterface $customer, int $storeId, int $status ): bool { $statusChanged = (int)$subscriber->getStatus() !== $status; $emailChanged = $subscriber->getEmail() !== $customer->getEmail(); if ($this->dontNeedToSaveSubscriber( $subscriber, $customer, $statusChanged, $storeId, $status, $emailChanged )) { return false; } if (!$subscriber->getId()) { $subscriber->setSubscriberConfirmCode($subscriber->randomSequence()); } $customerId = (int)$customer->getId(); $subscriber->setStatus($status) ->setStatusChanged($statusChanged) ->setCustomerId($customerId) ->setStoreId($storeId) ->setEmail($customer->getEmail()) ->save(); if ($statusChanged) { $this->customerSubscriberCache->setCustomerSubscriber($customerId, null); return true; } /** * If the subscriber is waiting to confirm from the customer * or customer changed the email * than need to send confirmation letter to the new email */ return $status === Subscriber::STATUS_NOT_ACTIVE || $emailChanged; } /** * Don't need to save subscriber model * * @param Subscriber $subscriber * @param CustomerInterface $customer * @param bool $statusChanged * @param int $storeId * @param int $status * @param bool $emailChanged * @return bool */ private function dontNeedToSaveSubscriber( Subscriber $subscriber, CustomerInterface $customer, bool $statusChanged, int $storeId, int $status, bool $emailChanged ): bool { return $subscriber->getId() && !$statusChanged && (int)$subscriber->getCustomerId() === (int)$customer->getId() && (int)$subscriber->getStoreId() === $storeId && !$emailChanged && $status !== Subscriber::STATUS_NOT_ACTIVE; } /** * Get new subscription status * * @param Subscriber $subscriber * @param CustomerInterface $customer * @param int $storeId * @param bool $subscribe * @return int */ private function getNewSubscriptionStatus( Subscriber $subscriber, CustomerInterface $customer, int $storeId, bool $subscribe ): int { $currentStatus = (int)$subscriber->getStatus(); // If the current status is already as needed then return them if (($subscribe && $currentStatus === Subscriber::STATUS_SUBSCRIBED) || (!$subscribe && $currentStatus === Subscriber::STATUS_UNSUBSCRIBED) ) { return $currentStatus; } $status = $currentStatus; if ($subscribe) { $customerConfirmStatus = $this->customerAccountManagement->getConfirmationStatus($customer->getId()); if ($customerConfirmStatus === AccountManagementInterface::ACCOUNT_CONFIRMATION_REQUIRED) { $status = Subscriber::STATUS_UNCONFIRMED; } elseif ($this->isConfirmNeed($storeId)) { $status = Subscriber::STATUS_NOT_ACTIVE; } else { $status = Subscriber::STATUS_SUBSCRIBED; } } elseif ($currentStatus === Subscriber::STATUS_SUBSCRIBED) { $status = Subscriber::STATUS_UNSUBSCRIBED; } return $status; } /** * Sends out email to customer after change subscription status * * @param Subscriber $subscriber * @return void */ private function sendEmailAfterChangeStatus(Subscriber $subscriber): void { $status = (int)$subscriber->getStatus(); if ($status === Subscriber::STATUS_UNCONFIRMED) { return; } try { switch ($status) { case Subscriber::STATUS_UNSUBSCRIBED: $subscriber->sendUnsubscriptionEmail(); break; case Subscriber::STATUS_SUBSCRIBED: $subscriber->sendConfirmationSuccessEmail(); break; case Subscriber::STATUS_NOT_ACTIVE: $subscriber->sendConfirmationRequestEmail(); break; } } catch (MailException $e) { // If we are not able to send a new account email, this should be ignored $this->logger->critical($e); } } /** * Is need to confirm subscription * * @param int $storeId * @return bool */ private function isConfirmNeed(int $storeId): bool { return (bool)$this->scopeConfig->isSetFlag( Subscriber::XML_PATH_CONFIRMATION_FLAG, ScopeInterface::SCOPE_STORE, $storeId ); } }