![]() 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/Controller/Account/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\Customer\Controller\Account; use Magento\Customer\Api\Data\CustomerInterface; use Magento\Customer\Api\SessionCleanerInterface; use Magento\Customer\Model\AccountConfirmation; use Magento\Customer\Model\AddressRegistry; use Magento\Customer\Model\Url; 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\FileSystemException; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\InvalidEmailOrPasswordException; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\SessionException; use Magento\Framework\Exception\State\UserLockedException; use Magento\Customer\Controller\AbstractAccount; use Magento\Framework\Phrase; use Magento\Framework\Filesystem; use Magento\Framework\App\Filesystem\DirectoryList; /** * Customer edit account information controller * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ class EditPost extends AbstractAccount implements CsrfAwareActionInterface, HttpPostActionInterface { /** * Form code for data extractor */ public const FORM_DATA_EXTRACTOR_CODE = 'customer_account_edit'; /** * @var AccountManagementInterface */ protected $accountManagement; /** * @var CustomerRepositoryInterface */ protected $customerRepository; /** * @var Validator */ protected $formKeyValidator; /** * @var CustomerExtractor */ protected $customerExtractor; /** * @var Session */ protected $session; /** * @var EmailNotificationInterface */ private $emailNotification; /** * @var AuthenticationInterface */ private $authentication; /** * @var Mapper */ private $customerMapper; /** * @var Escaper */ private $escaper; /** * @var AddressRegistry */ private $addressRegistry; /** * @var Filesystem */ private $filesystem; /** * @var SessionCleanerInterface */ private $sessionCleaner; /** * @var AccountConfirmation */ private $accountConfirmation; /** * @var Url */ private Url $customerUrl; /** * @param Context $context * @param Session $customerSession * @param AccountManagementInterface $accountManagement * @param CustomerRepositoryInterface $customerRepository * @param Validator $formKeyValidator * @param CustomerExtractor $customerExtractor * @param Escaper|null $escaper * @param AddressRegistry|null $addressRegistry * @param Filesystem|null $filesystem * @param SessionCleanerInterface|null $sessionCleaner * @param AccountConfirmation|null $accountConfirmation * @param Url|null $customerUrl */ public function __construct( Context $context, Session $customerSession, AccountManagementInterface $accountManagement, CustomerRepositoryInterface $customerRepository, Validator $formKeyValidator, CustomerExtractor $customerExtractor, ?Escaper $escaper = null, ?AddressRegistry $addressRegistry = null, ?Filesystem $filesystem = null, ?SessionCleanerInterface $sessionCleaner = null, ?AccountConfirmation $accountConfirmation = null, ?Url $customerUrl = null ) { parent::__construct($context); $this->session = $customerSession; $this->accountManagement = $accountManagement; $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); $this->filesystem = $filesystem ?: ObjectManager::getInstance()->get(Filesystem::class); $this->sessionCleaner = $sessionCleaner ?: ObjectManager::getInstance()->get(SessionCleanerInterface::class); $this->accountConfirmation = $accountConfirmation ?: ObjectManager::getInstance() ->get(AccountConfirmation::class); $this->customerUrl = $customerUrl ?: ObjectManager::getInstance()->get(Url::class); } /** * Get authentication * * @return AuthenticationInterface */ private function getAuthentication() { if (!($this->authentication instanceof AuthenticationInterface)) { return ObjectManager::getInstance()->get(AuthenticationInterface::class); } else { return $this->authentication; } } /** * Get email notification * * @return EmailNotificationInterface */ 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 { $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 Redirect * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @throws SessionException */ public function execute() { $resultRedirect = $this->resultRedirectFactory->create(); $validFormKey = $this->formKeyValidator->validate($this->getRequest()); if ($validFormKey && $this->getRequest()->isPost()) { $customer = $this->getCustomerDataObject($this->session->getCustomerId()); $customerCandidate = $this->populateNewCustomerDataObject($this->_request, $customer); $attributeToDelete = $this->_request->getParam('delete_attribute_value'); if ($attributeToDelete !== null) { $this->deleteCustomerFileAttribute($customerCandidate, $attributeToDelete); } try { // whether a customer enabled change email option $isEmailChanged = $this->processChangeEmailRequest($customer); // whether a customer enabled change password option $isPasswordChanged = $this->changeCustomerPassword($customer->getEmail()); // No need to validate customer address while editing customer profile $this->disableAddressValidation($customerCandidate); $this->customerRepository->save($customerCandidate); $updatedCustomer = $this->customerRepository->getById($customerCandidate->getId()); $this->getEmailNotification()->credentialsChanged( $updatedCustomer, $customer->getEmail(), $isPasswordChanged ); $this->dispatchSuccessEvent($updatedCustomer); $this->messageManager->addSuccessMessage(__('You saved the account information.')); // logout from current session if password or email changed. if ($isPasswordChanged || $isEmailChanged) { $this->session->logout(); $this->session->start(); $this->addComplexSuccessMessage($customer, $updatedCustomer); return $resultRedirect->setPath('customer/account/login'); } 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->addErrorMessage($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 (LocalizedException $e) { $this->messageManager->addErrorMessage($e->getMessage()); } catch (\Exception $e) { $this->messageManager->addException($e, __('We can\'t save the customer.')); } $this->session->setCustomerFormData($this->getRequest()->getPostValue()); } $resultRedirect = $this->resultRedirectFactory->create(); $resultRedirect->setPath('*/*/edit'); return $resultRedirect; } /** * Adds a complex success message if email confirmation is required * * @param CustomerInterface $outdatedCustomer * @param CustomerInterface $updatedCustomer * @throws LocalizedException */ private function addComplexSuccessMessage( CustomerInterface $outdatedCustomer, CustomerInterface $updatedCustomer ): void { if (($outdatedCustomer->getEmail() !== $updatedCustomer->getEmail()) && $this->accountConfirmation->isCustomerEmailChangedConfirmRequired($updatedCustomer)) { $this->messageManager->addComplexSuccessMessage( 'confirmAccountSuccessMessage', ['url' => $this->customerUrl->getEmailConfirmationUrl($updatedCustomer->getEmail())] ); } } /** * Account editing action completed successfully event * * @param CustomerInterface $customerCandidateDataObject * @return void */ private function dispatchSuccessEvent(CustomerInterface $customerCandidateDataObject) { $this->_eventManager->dispatch( 'customer_account_edited', ['email' => $customerCandidateDataObject->getEmail()] ); } /** * Get customer data object * * @param int $customerId * * @return CustomerInterface * @throws LocalizedException * @throws NoSuchEntityException */ private function getCustomerDataObject($customerId) { return $this->customerRepository->getById($customerId); } /** * Create Data Transfer Object of customer candidate * * @param RequestInterface $inputData * @param CustomerInterface $currentCustomerData * @return CustomerInterface */ private function populateNewCustomerDataObject( RequestInterface $inputData, 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|LocalizedException */ 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->accountManagement->changePassword($email, $currPass, $newPass); } return $isPasswordChanged; } /** * Process change email request * * @param CustomerInterface $currentCustomerDataObject * @return bool * @throws InvalidEmailOrPasswordException * @throws UserLockedException */ private function processChangeEmailRequest(CustomerInterface $currentCustomerDataObject) { if ($this->getRequest()->getParam('change_email')) { // authenticate user for changing email try { $this->getAuthentication()->authenticate( $currentCustomerDataObject->getId(), $this->getRequest()->getPost('current_password') ); $this->sessionCleaner->clearFor((int) $currentCustomerDataObject->getId()); return true; } catch (InvalidEmailOrPasswordException $e) { throw new InvalidEmailOrPasswordException( __("The password doesn't match this account. Verify the password and try again.") ); } } return false; } /** * Get Customer Mapper instance * * @return Mapper */ private function getCustomerMapper() { if ($this->customerMapper === null) { $this->customerMapper = ObjectManager::getInstance()->get(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); } } /** * Removes file attribute from customer entity and file from filesystem * * @param CustomerInterface $customerCandidateDataObject * @param string $attributeToDelete * @return void * @throws FileSystemException */ private function deleteCustomerFileAttribute( CustomerInterface $customerCandidateDataObject, string $attributeToDelete ) : void { if ($attributeToDelete !== '') { if (strpos($attributeToDelete, ',') !== false) { $attributes = explode(',', $attributeToDelete); } else { $attributes[] = $attributeToDelete; } foreach ($attributes as $attr) { $attributeValue = $customerCandidateDataObject->getCustomAttribute($attr); if ($attributeValue!== null) { if ($attributeValue->getValue() !== '') { $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); $fileName = $attributeValue->getValue(); $path = $mediaDirectory->getAbsolutePath('customer' . $fileName); if ($fileName && $mediaDirectory->isFile($path)) { $mediaDirectory->delete($path); } $customerCandidateDataObject->setCustomAttribute( $attr, '' ); } } } } } }