123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- <?php
- /**
- *
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Customer\Controller\Account;
- use Magento\Customer\Api\Data\CustomerInterface;
- use Magento\Customer\Model\AddressRegistry;
- use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
- use Magento\Customer\Model\AuthenticationInterface;
- use Magento\Customer\Model\Customer\Mapper;
- use Magento\Customer\Model\EmailNotificationInterface;
- use Magento\Framework\App\CsrfAwareActionInterface;
- use Magento\Framework\App\ObjectManager;
- use Magento\Framework\App\Request\InvalidRequestException;
- use Magento\Framework\App\RequestInterface;
- use Magento\Framework\Controller\Result\Redirect;
- use Magento\Framework\Data\Form\FormKey\Validator;
- use Magento\Customer\Api\AccountManagementInterface;
- use Magento\Customer\Api\CustomerRepositoryInterface;
- use Magento\Customer\Model\CustomerExtractor;
- use Magento\Customer\Model\Session;
- use Magento\Framework\App\Action\Context;
- use Magento\Framework\Escaper;
- use Magento\Framework\Exception\InputException;
- use Magento\Framework\Exception\InvalidEmailOrPasswordException;
- use Magento\Framework\Exception\NoSuchEntityException;
- use Magento\Framework\Exception\State\UserLockedException;
- use Magento\Customer\Controller\AbstractAccount;
- use Magento\Framework\Phrase;
- /**
- * Class EditPost
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class EditPost extends AbstractAccount implements CsrfAwareActionInterface, HttpPostActionInterface
- {
- /**
- * Form code for data extractor
- */
- const FORM_DATA_EXTRACTOR_CODE = 'customer_account_edit';
- /**
- * @var AccountManagementInterface
- */
- protected $customerAccountManagement;
- /**
- * @var CustomerRepositoryInterface
- */
- protected $customerRepository;
- /**
- * @var Validator
- */
- protected $formKeyValidator;
- /**
- * @var CustomerExtractor
- */
- protected $customerExtractor;
- /**
- * @var Session
- */
- protected $session;
- /**
- * @var \Magento\Customer\Model\EmailNotificationInterface
- */
- private $emailNotification;
- /**
- * @var AuthenticationInterface
- */
- private $authentication;
- /**
- * @var Mapper
- */
- private $customerMapper;
- /**
- * @var Escaper
- */
- private $escaper;
- /**
- * @var AddressRegistry
- */
- private $addressRegistry;
- /**
- * @param Context $context
- * @param Session $customerSession
- * @param AccountManagementInterface $customerAccountManagement
- * @param CustomerRepositoryInterface $customerRepository
- * @param Validator $formKeyValidator
- * @param CustomerExtractor $customerExtractor
- * @param Escaper|null $escaper
- * @param AddressRegistry|null $addressRegistry
- */
- public function __construct(
- Context $context,
- Session $customerSession,
- AccountManagementInterface $customerAccountManagement,
- CustomerRepositoryInterface $customerRepository,
- Validator $formKeyValidator,
- CustomerExtractor $customerExtractor,
- ?Escaper $escaper = null,
- AddressRegistry $addressRegistry = null
- ) {
- parent::__construct($context);
- $this->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);
- }
- }
- }
|