session = $customerSession; $this->customerAccountManagement = $customerAccountManagement; $this->customerRepository = $customerRepository; $this->formKeyValidator = $formKeyValidator; $this->customerExtractor = $customerExtractor; $this->escaper = $escaper ?: ObjectManager::getInstance()->get(Escaper::class); $this->addressRegistry = $addressRegistry ?: ObjectManager::getInstance()->get(AddressRegistry::class); } /** * Get authentication * * @return AuthenticationInterface */ private function getAuthentication() { if (!($this->authentication instanceof AuthenticationInterface)) { return ObjectManager::getInstance()->get( \Magento\Customer\Model\AuthenticationInterface::class ); } else { return $this->authentication; } } /** * Get email notification * * @return EmailNotificationInterface * @deprecated 100.1.0 */ private function getEmailNotification() { if (!($this->emailNotification instanceof EmailNotificationInterface)) { return ObjectManager::getInstance()->get( EmailNotificationInterface::class ); } else { return $this->emailNotification; } } /** * @inheritDoc */ public function createCsrfValidationException( RequestInterface $request ): ?InvalidRequestException { /** @var Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); $resultRedirect->setPath('*/*/edit'); return new InvalidRequestException( $resultRedirect, [new Phrase('Invalid Form Key. Please refresh the page.')] ); } /** * @inheritDoc */ public function validateForCsrf(RequestInterface $request): ?bool { return null; } /** * Change customer email or password action * * @return \Magento\Framework\Controller\Result\Redirect */ public function execute() { /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); $validFormKey = $this->formKeyValidator->validate($this->getRequest()); if ($validFormKey && $this->getRequest()->isPost()) { $currentCustomerDataObject = $this->getCustomerDataObject($this->session->getCustomerId()); $customerCandidateDataObject = $this->populateNewCustomerDataObject( $this->_request, $currentCustomerDataObject ); try { // whether a customer enabled change email option $this->processChangeEmailRequest($currentCustomerDataObject); // whether a customer enabled change password option $isPasswordChanged = $this->changeCustomerPassword($currentCustomerDataObject->getEmail()); // No need to validate customer address while editing customer profile $this->disableAddressValidation($customerCandidateDataObject); $this->customerRepository->save($customerCandidateDataObject); $this->getEmailNotification()->credentialsChanged( $customerCandidateDataObject, $currentCustomerDataObject->getEmail(), $isPasswordChanged ); $this->dispatchSuccessEvent($customerCandidateDataObject); $this->messageManager->addSuccess(__('You saved the account information.')); return $resultRedirect->setPath('customer/account'); } catch (InvalidEmailOrPasswordException $e) { $this->messageManager->addErrorMessage($this->escaper->escapeHtml($e->getMessage())); } catch (UserLockedException $e) { $message = __( 'The account sign-in was incorrect or your account is disabled temporarily. ' . 'Please wait and try again later.' ); $this->session->logout(); $this->session->start(); $this->messageManager->addError($message); return $resultRedirect->setPath('customer/account/login'); } catch (InputException $e) { $this->messageManager->addErrorMessage($this->escaper->escapeHtml($e->getMessage())); foreach ($e->getErrors() as $error) { $this->messageManager->addErrorMessage($this->escaper->escapeHtml($error->getMessage())); } } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->messageManager->addError($e->getMessage()); } catch (\Exception $e) { $this->messageManager->addException($e, __('We can\'t save the customer.')); } $this->session->setCustomerFormData($this->getRequest()->getPostValue()); } /** @var Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); $resultRedirect->setPath('*/*/edit'); return $resultRedirect; } /** * Account editing action completed successfully event * * @param \Magento\Customer\Api\Data\CustomerInterface $customerCandidateDataObject * @return void */ private function dispatchSuccessEvent(\Magento\Customer\Api\Data\CustomerInterface $customerCandidateDataObject) { $this->_eventManager->dispatch( 'customer_account_edited', ['email' => $customerCandidateDataObject->getEmail()] ); } /** * Get customer data object * * @param int $customerId * * @return \Magento\Customer\Api\Data\CustomerInterface */ private function getCustomerDataObject($customerId) { return $this->customerRepository->getById($customerId); } /** * Create Data Transfer Object of customer candidate * * @param \Magento\Framework\App\RequestInterface $inputData * @param \Magento\Customer\Api\Data\CustomerInterface $currentCustomerData * @return \Magento\Customer\Api\Data\CustomerInterface */ private function populateNewCustomerDataObject( \Magento\Framework\App\RequestInterface $inputData, \Magento\Customer\Api\Data\CustomerInterface $currentCustomerData ) { $attributeValues = $this->getCustomerMapper()->toFlatArray($currentCustomerData); $customerDto = $this->customerExtractor->extract( self::FORM_DATA_EXTRACTOR_CODE, $inputData, $attributeValues ); $customerDto->setId($currentCustomerData->getId()); if (!$customerDto->getAddresses()) { $customerDto->setAddresses($currentCustomerData->getAddresses()); } if (!$inputData->getParam('change_email')) { $customerDto->setEmail($currentCustomerData->getEmail()); } return $customerDto; } /** * Change customer password * * @param string $email * @return boolean * @throws InvalidEmailOrPasswordException|InputException */ protected function changeCustomerPassword($email) { $isPasswordChanged = false; if ($this->getRequest()->getParam('change_password')) { $currPass = $this->getRequest()->getPost('current_password'); $newPass = $this->getRequest()->getPost('password'); $confPass = $this->getRequest()->getPost('password_confirmation'); if ($newPass != $confPass) { throw new InputException(__('Password confirmation doesn\'t match entered password.')); } $isPasswordChanged = $this->customerAccountManagement->changePassword($email, $currPass, $newPass); } return $isPasswordChanged; } /** * Process change email request * * @param \Magento\Customer\Api\Data\CustomerInterface $currentCustomerDataObject * @return void * @throws InvalidEmailOrPasswordException * @throws UserLockedException */ private function processChangeEmailRequest(\Magento\Customer\Api\Data\CustomerInterface $currentCustomerDataObject) { if ($this->getRequest()->getParam('change_email')) { // authenticate user for changing email try { $this->getAuthentication()->authenticate( $currentCustomerDataObject->getId(), $this->getRequest()->getPost('current_password') ); } catch (InvalidEmailOrPasswordException $e) { throw new InvalidEmailOrPasswordException( __("The password doesn't match this account. Verify the password and try again.") ); } } } /** * Get Customer Mapper instance * * @return Mapper * * @deprecated 100.1.3 */ private function getCustomerMapper() { if ($this->customerMapper === null) { $this->customerMapper = ObjectManager::getInstance()->get(\Magento\Customer\Model\Customer\Mapper::class); } return $this->customerMapper; } /** * Disable Customer Address Validation * * @param CustomerInterface $customer * @throws NoSuchEntityException */ private function disableAddressValidation($customer) { foreach ($customer->getAddresses() as $address) { $addressModel = $this->addressRegistry->retrieve($address->getId()); $addressModel->setShouldIgnoreValidation(true); } } }