![]() 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-customer/Model/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\Customer\Model; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\MailException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Mail\Template\SenderResolverInterface; use Magento\Store\Model\App\Emulation; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\Mail\Template\TransportBuilder; use Magento\Customer\Helper\View as CustomerViewHelper; use Magento\Customer\Api\Data\CustomerInterface; use Magento\Framework\Reflection\DataObjectProcessor; use Magento\Framework\Exception\LocalizedException; use Magento\Store\Model\ScopeInterface; use Magento\Customer\Model\Data\CustomerSecure; /** * Customer email notification * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class EmailNotification implements EmailNotificationInterface { /**#@+ * Configuration paths for email templates and identities */ public const XML_PATH_FORGOT_EMAIL_IDENTITY = 'customer/password/forgot_email_identity'; public const XML_PATH_RESET_PASSWORD_TEMPLATE = 'customer/password/reset_password_template'; public const XML_PATH_CHANGE_EMAIL_TEMPLATE = 'customer/account_information/change_email_template'; public const XML_PATH_CHANGE_EMAIL_AND_PASSWORD_TEMPLATE = 'customer/account_information/change_email_and_password_template'; public const XML_PATH_FORGOT_EMAIL_TEMPLATE = 'customer/password/forgot_email_template'; public const XML_PATH_REMIND_EMAIL_TEMPLATE = 'customer/password/remind_email_template'; public const XML_PATH_REGISTER_EMAIL_IDENTITY = 'customer/create_account/email_identity'; public const XML_PATH_REGISTER_EMAIL_TEMPLATE = 'customer/create_account/email_template'; public const XML_PATH_REGISTER_NO_PASSWORD_EMAIL_TEMPLATE = 'customer/create_account/email_no_password_template'; public const XML_PATH_CONFIRM_EMAIL_TEMPLATE = 'customer/create_account/email_confirmation_template'; public const XML_PATH_CONFIRMED_EMAIL_TEMPLATE = 'customer/create_account/email_confirmed_template'; /** * self::NEW_ACCOUNT_EMAIL_REGISTERED welcome email, when confirmation is disabled * and password is set * self::NEW_ACCOUNT_EMAIL_REGISTERED_NO_PASSWORD welcome email, when confirmation is disabled * and password is not set * self::NEW_ACCOUNT_EMAIL_CONFIRMED welcome email, when confirmation is enabled * and password is set * self::NEW_ACCOUNT_EMAIL_CONFIRMATION email with confirmation link */ public const TEMPLATE_TYPES = [ self::NEW_ACCOUNT_EMAIL_REGISTERED => self::XML_PATH_REGISTER_EMAIL_TEMPLATE, self::NEW_ACCOUNT_EMAIL_REGISTERED_NO_PASSWORD => self::XML_PATH_REGISTER_NO_PASSWORD_EMAIL_TEMPLATE, self::NEW_ACCOUNT_EMAIL_CONFIRMED => self::XML_PATH_CONFIRMED_EMAIL_TEMPLATE, self::NEW_ACCOUNT_EMAIL_CONFIRMATION => self::XML_PATH_CONFIRM_EMAIL_TEMPLATE, ]; /**#@-*/ /** * @var CustomerRegistry */ private $customerRegistry; /** * @var StoreManagerInterface */ private $storeManager; /** * @var TransportBuilder */ private $transportBuilder; /** * @var CustomerViewHelper */ protected $customerViewHelper; /** * @var DataObjectProcessor */ protected $dataProcessor; /** * @var ScopeConfigInterface */ private $scopeConfig; /** * @var SenderResolverInterface */ private $senderResolver; /** * @var Emulation */ private $emulation; /** * @var AccountConfirmation */ private AccountConfirmation $accountConfirmation; /** * @param CustomerRegistry $customerRegistry * @param StoreManagerInterface $storeManager * @param TransportBuilder $transportBuilder * @param CustomerViewHelper $customerViewHelper * @param DataObjectProcessor $dataProcessor * @param ScopeConfigInterface $scopeConfig * @param SenderResolverInterface|null $senderResolver * @param Emulation|null $emulation * @param AccountConfirmation|null $accountConfirmation */ public function __construct( CustomerRegistry $customerRegistry, StoreManagerInterface $storeManager, TransportBuilder $transportBuilder, CustomerViewHelper $customerViewHelper, DataObjectProcessor $dataProcessor, ScopeConfigInterface $scopeConfig, SenderResolverInterface $senderResolver = null, Emulation $emulation = null, ?AccountConfirmation $accountConfirmation = null ) { $this->customerRegistry = $customerRegistry; $this->storeManager = $storeManager; $this->transportBuilder = $transportBuilder; $this->customerViewHelper = $customerViewHelper; $this->dataProcessor = $dataProcessor; $this->scopeConfig = $scopeConfig; $this->senderResolver = $senderResolver ?? ObjectManager::getInstance()->get(SenderResolverInterface::class); $this->emulation = $emulation ?? ObjectManager::getInstance()->get(Emulation::class); $this->accountConfirmation = $accountConfirmation ?? ObjectManager::getInstance() ->get(AccountConfirmation::class); } /** * Send notification to customer when email or/and password changed * * @param CustomerInterface $savedCustomer * @param string $origCustomerEmail * @param bool $isPasswordChanged * @return void * @throws LocalizedException */ public function credentialsChanged( CustomerInterface $savedCustomer, $origCustomerEmail, $isPasswordChanged = false ): void { if ($origCustomerEmail != $savedCustomer->getEmail()) { $this->emailChangedConfirmation($savedCustomer); if ($isPasswordChanged) { $this->emailAndPasswordChanged($savedCustomer, $origCustomerEmail); $this->emailAndPasswordChanged($savedCustomer, $savedCustomer->getEmail()); return; } $this->emailChanged($savedCustomer, $origCustomerEmail); $this->emailChanged($savedCustomer, $savedCustomer->getEmail()); return; } if ($isPasswordChanged) { $this->passwordReset($savedCustomer); } } /** * Send email to customer when his email and password is changed * * @param CustomerInterface $customer * @param string $email * @return void * @throws MailException * @throws NoSuchEntityException|LocalizedException */ private function emailAndPasswordChanged(CustomerInterface $customer, $email): void { $storeId = $customer->getStoreId(); if ($storeId === null) { $storeId = $this->getWebsiteStoreId($customer); } $customerEmailData = $this->getFullCustomerObject($customer); $this->sendEmailTemplate( $customer, self::XML_PATH_CHANGE_EMAIL_AND_PASSWORD_TEMPLATE, self::XML_PATH_FORGOT_EMAIL_IDENTITY, ['customer' => $customerEmailData, 'store' => $this->storeManager->getStore($storeId)], $storeId, $email ); } /** * Send email to customer when his email is changed * * @param CustomerInterface $customer * @param string $email * @return void * @throws MailException * @throws NoSuchEntityException|LocalizedException */ private function emailChanged(CustomerInterface $customer, $email): void { $storeId = $customer->getStoreId(); if ($storeId === null) { $storeId = $this->getWebsiteStoreId($customer); } $customerEmailData = $this->getFullCustomerObject($customer); $this->sendEmailTemplate( $customer, self::XML_PATH_CHANGE_EMAIL_TEMPLATE, self::XML_PATH_FORGOT_EMAIL_IDENTITY, ['customer' => $customerEmailData, 'store' => $this->storeManager->getStore($storeId)], $storeId, $email ); } /** * Send email to customer when his password is reset * * @param CustomerInterface $customer * @return void * @throws MailException * @throws NoSuchEntityException|LocalizedException */ private function passwordReset(CustomerInterface $customer): void { $storeId = $customer->getStoreId(); if ($storeId === null) { $storeId = $this->getWebsiteStoreId($customer); } $customerEmailData = $this->getFullCustomerObject($customer); $this->sendEmailTemplate( $customer, self::XML_PATH_RESET_PASSWORD_TEMPLATE, self::XML_PATH_FORGOT_EMAIL_IDENTITY, ['customer' => $customerEmailData, 'store' => $this->storeManager->getStore($storeId)], $storeId ); } /** * Send corresponding email template * * @param CustomerInterface $customer * @param string $template configuration path of email template * @param string $sender configuration path of email identity * @param array $templateParams * @param int|null $storeId * @param string $email * @return void * @throws MailException|LocalizedException */ private function sendEmailTemplate( $customer, $template, $sender, $templateParams = [], $storeId = null, $email = null ): void { $templateId = $this->scopeConfig->getValue($template, ScopeInterface::SCOPE_STORE, $storeId); if ($email === null) { $email = $customer->getEmail(); } /** @var array $from */ $from = $this->senderResolver->resolve( $this->scopeConfig->getValue($sender, ScopeInterface::SCOPE_STORE, $storeId), $storeId ); $transport = $this->transportBuilder->setTemplateIdentifier($templateId) ->setTemplateOptions(['area' => 'frontend', 'store' => $storeId]) ->setTemplateVars($templateParams) ->setFrom($from) ->addTo($email, $this->customerViewHelper->getCustomerName($customer)) ->getTransport(); $this->emulation->startEnvironmentEmulation($storeId, \Magento\Framework\App\Area::AREA_FRONTEND); $transport->sendMessage(); $this->emulation->stopEnvironmentEmulation(); } /** * Create an object with data merged from Customer and CustomerSecure * * @param CustomerInterface $customer * @return CustomerSecure * @throws NoSuchEntityException */ private function getFullCustomerObject($customer): CustomerSecure { // No need to flatten the custom attributes or nested objects since the only usage is for email templates and // object passed for events $mergedCustomerData = $this->customerRegistry->retrieveSecureData($customer->getId()); $customerData = $this->dataProcessor ->buildOutputDataArray($customer, CustomerInterface::class); $mergedCustomerData->addData($customerData); $mergedCustomerData->setData('name', $this->customerViewHelper->getCustomerName($customer)); return $mergedCustomerData; } /** * Get either first store ID from a set website or the provided as default * * @param CustomerInterface $customer * @param int|string|null $defaultStoreId * @return int * @throws LocalizedException */ private function getWebsiteStoreId($customer, $defaultStoreId = null): int { if ($customer->getWebsiteId() != 0 && empty($defaultStoreId)) { $storeIds = $this->storeManager->getWebsite($customer->getWebsiteId())->getStoreIds(); $defaultStoreId = reset($storeIds); } return $defaultStoreId; } /** * Send email with new customer password * * @param CustomerInterface $customer * @return void * @throws LocalizedException * @throws MailException * @throws NoSuchEntityException */ public function passwordReminder(CustomerInterface $customer): void { $storeId = $customer->getStoreId(); if ($storeId === null) { $storeId = $this->getWebsiteStoreId($customer); } $customerEmailData = $this->getFullCustomerObject($customer); $this->sendEmailTemplate( $customer, self::XML_PATH_REMIND_EMAIL_TEMPLATE, self::XML_PATH_FORGOT_EMAIL_IDENTITY, ['customer' => $customerEmailData, 'store' => $this->storeManager->getStore($storeId)], $storeId ); } /** * Send email with reset password confirmation link * * @param CustomerInterface $customer * @return void * @throws LocalizedException * @throws MailException * @throws NoSuchEntityException */ public function passwordResetConfirmation(CustomerInterface $customer): void { $storeId = $customer->getStoreId(); if ($storeId === null) { $storeId = $this->getWebsiteStoreId($customer); } $customerEmailData = $this->getFullCustomerObject($customer); $this->sendEmailTemplate( $customer, self::XML_PATH_FORGOT_EMAIL_TEMPLATE, self::XML_PATH_FORGOT_EMAIL_IDENTITY, ['customer' => $customerEmailData, 'store' => $this->storeManager->getStore($storeId)], $storeId ); } /** * Send email with new account related information * * @param CustomerInterface $customer * @param string $type * @param string $backUrl * @param int|null $storeId * @param string $sendemailStoreId * @return void * @throws LocalizedException */ public function newAccount( CustomerInterface $customer, $type = self::NEW_ACCOUNT_EMAIL_REGISTERED, $backUrl = '', $storeId = null, $sendemailStoreId = null ): void { $types = self::TEMPLATE_TYPES; if (!isset($types[$type])) { throw new LocalizedException( __('The transactional account email type is incorrect. Verify and try again.') ); } if ($storeId === null) { $storeId = $this->getWebsiteStoreId($customer, $sendemailStoreId); } $store = $this->storeManager->getStore($customer->getStoreId()); $customerEmailData = $this->getFullCustomerObject($customer); $this->sendEmailTemplate( $customer, $types[$type], self::XML_PATH_REGISTER_EMAIL_IDENTITY, ['customer' => $customerEmailData, 'back_url' => $backUrl, 'store' => $store], $storeId ); } /** * Sending an email to confirm the email address in case the email address has been changed * * @param CustomerInterface $customer * @throws LocalizedException */ private function emailChangedConfirmation(CustomerInterface $customer): void { if (!$this->accountConfirmation->isCustomerEmailChangedConfirmRequired($customer)) { return; } $this->newAccount($customer, self::NEW_ACCOUNT_EMAIL_CONFIRMATION, null, $customer->getStoreId()); } }