123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Customer\Controller\Adminhtml\Index;
- use Magento\Customer\Api\AccountManagementInterface;
- use Magento\Customer\Api\AddressRepositoryInterface;
- use Magento\Customer\Api\CustomerRepositoryInterface;
- use Magento\Customer\Model\Address\Mapper;
- use Magento\Customer\Model\AddressRegistry;
- use Magento\Framework\Api\DataObjectHelper;
- use Magento\Customer\Api\Data\AddressInterfaceFactory;
- use Magento\Customer\Api\Data\CustomerInterfaceFactory;
- use Magento\Framework\DataObjectFactory as ObjectFactory;
- use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
- use Magento\Customer\Api\AddressMetadataInterface;
- use Magento\Customer\Api\CustomerMetadataInterface;
- use Magento\Customer\Api\Data\CustomerInterface;
- use Magento\Customer\Controller\RegistryConstants;
- use Magento\Customer\Model\EmailNotificationInterface;
- use Magento\Customer\Model\Metadata\Form;
- use Magento\Framework\Exception\LocalizedException;
- use Magento\Framework\Exception\NoSuchEntityException;
- use Magento\Framework\App\ObjectManager;
- /**
- * Save customer action.
- *
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class Save extends \Magento\Customer\Controller\Adminhtml\Index implements HttpPostActionInterface
- {
- /**
- * @var EmailNotificationInterface
- */
- private $emailNotification;
- /**
- * @var AddressRegistry
- */
- private $addressRegistry;
- /**
- * Constructor
- *
- * @param \Magento\Backend\App\Action\Context $context
- * @param \Magento\Framework\Registry $coreRegistry
- * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
- * @param \Magento\Customer\Model\CustomerFactory $customerFactory
- * @param \Magento\Customer\Model\AddressFactory $addressFactory
- * @param \Magento\Customer\Model\Metadata\FormFactory $formFactory
- * @param \Magento\Newsletter\Model\SubscriberFactory $subscriberFactory
- * @param \Magento\Customer\Helper\View $viewHelper
- * @param \Magento\Framework\Math\Random $random
- * @param CustomerRepositoryInterface $customerRepository
- * @param \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter
- * @param Mapper $addressMapper
- * @param AccountManagementInterface $customerAccountManagement
- * @param AddressRepositoryInterface $addressRepository
- * @param CustomerInterfaceFactory $customerDataFactory
- * @param AddressInterfaceFactory $addressDataFactory
- * @param \Magento\Customer\Model\Customer\Mapper $customerMapper
- * @param \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor
- * @param DataObjectHelper $dataObjectHelper
- * @param ObjectFactory $objectFactory
- * @param \Magento\Framework\View\LayoutFactory $layoutFactory
- * @param \Magento\Framework\View\Result\LayoutFactory $resultLayoutFactory
- * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
- * @param \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory
- * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
- * @param AddressRegistry|null $addressRegistry
- * @SuppressWarnings(PHPMD.ExcessiveParameterList)
- */
- public function __construct(
- \Magento\Backend\App\Action\Context $context,
- \Magento\Framework\Registry $coreRegistry,
- \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
- \Magento\Customer\Model\CustomerFactory $customerFactory,
- \Magento\Customer\Model\AddressFactory $addressFactory,
- \Magento\Customer\Model\Metadata\FormFactory $formFactory,
- \Magento\Newsletter\Model\SubscriberFactory $subscriberFactory,
- \Magento\Customer\Helper\View $viewHelper,
- \Magento\Framework\Math\Random $random,
- CustomerRepositoryInterface $customerRepository,
- \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter,
- Mapper $addressMapper,
- AccountManagementInterface $customerAccountManagement,
- AddressRepositoryInterface $addressRepository,
- CustomerInterfaceFactory $customerDataFactory,
- AddressInterfaceFactory $addressDataFactory,
- \Magento\Customer\Model\Customer\Mapper $customerMapper,
- \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor,
- DataObjectHelper $dataObjectHelper,
- ObjectFactory $objectFactory,
- \Magento\Framework\View\LayoutFactory $layoutFactory,
- \Magento\Framework\View\Result\LayoutFactory $resultLayoutFactory,
- \Magento\Framework\View\Result\PageFactory $resultPageFactory,
- \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory,
- \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
- AddressRegistry $addressRegistry = null
- ) {
- parent::__construct(
- $context,
- $coreRegistry,
- $fileFactory,
- $customerFactory,
- $addressFactory,
- $formFactory,
- $subscriberFactory,
- $viewHelper,
- $random,
- $customerRepository,
- $extensibleDataObjectConverter,
- $addressMapper,
- $customerAccountManagement,
- $addressRepository,
- $customerDataFactory,
- $addressDataFactory,
- $customerMapper,
- $dataObjectProcessor,
- $dataObjectHelper,
- $objectFactory,
- $layoutFactory,
- $resultLayoutFactory,
- $resultPageFactory,
- $resultForwardFactory,
- $resultJsonFactory
- );
- $this->addressRegistry = $addressRegistry ?: ObjectManager::getInstance()->get(AddressRegistry::class);
- }
- /**
- * Reformat customer account data to be compatible with customer service interface
- *
- * @return array
- */
- protected function _extractCustomerData()
- {
- $customerData = [];
- if ($this->getRequest()->getPost('customer')) {
- $additionalAttributes = [
- CustomerInterface::DEFAULT_BILLING,
- CustomerInterface::DEFAULT_SHIPPING,
- 'confirmation',
- 'sendemail_store_id',
- 'extension_attributes',
- ];
- $customerData = $this->_extractData(
- 'adminhtml_customer',
- CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,
- $additionalAttributes,
- 'customer'
- );
- }
- if (isset($customerData['disable_auto_group_change'])) {
- $customerData['disable_auto_group_change'] = (int) filter_var(
- $customerData['disable_auto_group_change'],
- FILTER_VALIDATE_BOOLEAN
- );
- }
- return $customerData;
- }
- /**
- * Perform customer data filtration based on form code and form object
- *
- * @param string $formCode The code of EAV form to take the list of attributes from
- * @param string $entityType entity type for the form
- * @param string[] $additionalAttributes The list of attribute codes to skip filtration for
- * @param string $scope scope of the request
- * @return array
- */
- protected function _extractData(
- $formCode,
- $entityType,
- $additionalAttributes = [],
- $scope = null
- ) {
- $metadataForm = $this->getMetadataForm($entityType, $formCode, $scope);
- $formData = $metadataForm->extractData($this->getRequest(), $scope);
- $formData = $metadataForm->compactData($formData);
- // Initialize additional attributes
- /** @var \Magento\Framework\DataObject $object */
- $object = $this->_objectFactory->create(['data' => $this->getRequest()->getPostValue()]);
- $requestData = $object->getData($scope);
- foreach ($additionalAttributes as $attributeCode) {
- $formData[$attributeCode] = isset($requestData[$attributeCode]) ? $requestData[$attributeCode] : false;
- }
- // Unset unused attributes
- $formAttributes = $metadataForm->getAttributes();
- foreach ($formAttributes as $attribute) {
- /** @var \Magento\Customer\Api\Data\AttributeMetadataInterface $attribute */
- $attributeCode = $attribute->getAttributeCode();
- if ($attribute->getFrontendInput() != 'boolean'
- && $formData[$attributeCode] === false
- ) {
- unset($formData[$attributeCode]);
- }
- }
- if (empty($formData['extension_attributes'])) {
- unset($formData['extension_attributes']);
- }
- return $formData;
- }
- /**
- * Saves default_billing and default_shipping flags for customer address
- *
- * @deprecated 102.0.1 must be removed because addresses are save separately for now
- * @param array $addressIdList
- * @param array $extractedCustomerData
- * @return array
- */
- protected function saveDefaultFlags(array $addressIdList, array & $extractedCustomerData)
- {
- $result = [];
- $extractedCustomerData[CustomerInterface::DEFAULT_BILLING] = null;
- $extractedCustomerData[CustomerInterface::DEFAULT_SHIPPING] = null;
- foreach ($addressIdList as $addressId) {
- $scope = sprintf('address/%s', $addressId);
- $addressData = $this->_extractData(
- 'adminhtml_customer_address',
- AddressMetadataInterface::ENTITY_TYPE_ADDRESS,
- ['default_billing', 'default_shipping'],
- $scope
- );
- if (is_numeric($addressId)) {
- $addressData['id'] = $addressId;
- }
- // Set default billing and shipping flags to customer
- if (!empty($addressData['default_billing']) && $addressData['default_billing'] === 'true') {
- $extractedCustomerData[CustomerInterface::DEFAULT_BILLING] = $addressId;
- $addressData['default_billing'] = true;
- } else {
- $addressData['default_billing'] = false;
- }
- if (!empty($addressData['default_shipping']) && $addressData['default_shipping'] === 'true') {
- $extractedCustomerData[CustomerInterface::DEFAULT_SHIPPING] = $addressId;
- $addressData['default_shipping'] = true;
- } else {
- $addressData['default_shipping'] = false;
- }
- $result[] = $addressData;
- }
- return $result;
- }
- /**
- * Reformat customer addresses data to be compatible with customer service interface
- *
- * @deprecated 102.0.1 addresses are saved separately for now
- * @param array $extractedCustomerData
- * @return array
- */
- protected function _extractCustomerAddressData(array & $extractedCustomerData)
- {
- $addresses = $this->getRequest()->getPost('address');
- $result = [];
- if (is_array($addresses)) {
- if (isset($addresses['_template_'])) {
- unset($addresses['_template_']);
- }
- $addressIdList = array_keys($addresses);
- $result = $this->saveDefaultFlags($addressIdList, $extractedCustomerData);
- }
- return $result;
- }
- /**
- * Save customer action
- *
- * @return \Magento\Backend\Model\View\Result\Redirect
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
- * @SuppressWarnings(PHPMD.NPathComplexity)
- */
- public function execute()
- {
- $returnToEdit = false;
- $originalRequestData = $this->getRequest()->getPostValue();
- $customerId = $this->getCurrentCustomerId();
- if ($originalRequestData) {
- try {
- // optional fields might be set in request for future processing by observers in other modules
- $customerData = $this->_extractCustomerData();
- if ($customerId) {
- $currentCustomer = $this->_customerRepository->getById($customerId);
- // No need to validate customer address while editing customer profile
- $this->disableAddressValidation($currentCustomer);
- $customerData = array_merge(
- $this->customerMapper->toFlatArray($currentCustomer),
- $customerData
- );
- $customerData['id'] = $customerId;
- }
- /** @var CustomerInterface $customer */
- $customer = $this->customerDataFactory->create();
- $this->dataObjectHelper->populateWithArray(
- $customer,
- $customerData,
- \Magento\Customer\Api\Data\CustomerInterface::class
- );
- $this->_eventManager->dispatch(
- 'adminhtml_customer_prepare_save',
- ['customer' => $customer, 'request' => $this->getRequest()]
- );
- if (isset($customerData['sendemail_store_id'])) {
- $customer->setStoreId($customerData['sendemail_store_id']);
- }
- // Save customer
- if ($customerId) {
- $this->_customerRepository->save($customer);
- $this->getEmailNotification()->credentialsChanged($customer, $currentCustomer->getEmail());
- } else {
- $customer = $this->customerAccountManagement->createAccount($customer);
- $customerId = $customer->getId();
- }
- $isSubscribed = null;
- if ($this->_authorization->isAllowed(null)) {
- $isSubscribed = $this->getRequest()->getPost('subscription');
- }
- if ($isSubscribed !== null) {
- if ($isSubscribed !== '0') {
- $this->_subscriberFactory->create()->subscribeCustomerById($customerId);
- } else {
- $this->_subscriberFactory->create()->unsubscribeCustomerById($customerId);
- }
- }
- // After save
- $this->_eventManager->dispatch(
- 'adminhtml_customer_save_after',
- ['customer' => $customer, 'request' => $this->getRequest()]
- );
- $this->_getSession()->unsCustomerFormData();
- // Done Saving customer, finish save action
- $this->_coreRegistry->register(RegistryConstants::CURRENT_CUSTOMER_ID, $customerId);
- $this->messageManager->addSuccess(__('You saved the customer.'));
- $returnToEdit = (bool)$this->getRequest()->getParam('back', false);
- } catch (\Magento\Framework\Validator\Exception $exception) {
- $messages = $exception->getMessages();
- if (empty($messages)) {
- $messages = $exception->getMessage();
- }
- $this->_addSessionErrorMessages($messages);
- $this->_getSession()->setCustomerFormData($originalRequestData);
- $returnToEdit = true;
- } catch (\Magento\Framework\Exception\AbstractAggregateException $exception) {
- $errors = $exception->getErrors();
- $messages = [];
- foreach ($errors as $error) {
- $messages[] = $error->getMessage();
- }
- $this->_addSessionErrorMessages($messages);
- $this->_getSession()->setCustomerFormData($originalRequestData);
- $returnToEdit = true;
- } catch (LocalizedException $exception) {
- $this->_addSessionErrorMessages($exception->getMessage());
- $this->_getSession()->setCustomerFormData($originalRequestData);
- $returnToEdit = true;
- } catch (\Exception $exception) {
- $this->messageManager->addException($exception, __('Something went wrong while saving the customer.'));
- $this->_getSession()->setCustomerFormData($originalRequestData);
- $returnToEdit = true;
- }
- }
- $resultRedirect = $this->resultRedirectFactory->create();
- if ($returnToEdit) {
- if ($customerId) {
- $resultRedirect->setPath(
- 'customer/*/edit',
- ['id' => $customerId, '_current' => true]
- );
- } else {
- $resultRedirect->setPath(
- 'customer/*/new',
- ['_current' => true]
- );
- }
- } else {
- $resultRedirect->setPath('customer/index');
- }
- return $resultRedirect;
- }
- /**
- * Get email notification
- *
- * @return EmailNotificationInterface
- * @deprecated 100.1.0
- */
- private function getEmailNotification()
- {
- if (!($this->emailNotification instanceof EmailNotificationInterface)) {
- return \Magento\Framework\App\ObjectManager::getInstance()->get(
- EmailNotificationInterface::class
- );
- } else {
- return $this->emailNotification;
- }
- }
- /**
- * Get metadata form
- *
- * @param string $entityType
- * @param string $formCode
- * @param string $scope
- * @return Form
- */
- private function getMetadataForm($entityType, $formCode, $scope)
- {
- $attributeValues = [];
- if ($entityType == CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER) {
- $customerId = $this->getCurrentCustomerId();
- if ($customerId) {
- $customer = $this->_customerRepository->getById($customerId);
- $attributeValues = $this->customerMapper->toFlatArray($customer);
- }
- }
- if ($entityType == AddressMetadataInterface::ENTITY_TYPE_ADDRESS) {
- $scopeData = explode('/', $scope);
- if (isset($scopeData[1]) && is_numeric($scopeData[1])) {
- $customerAddress = $this->addressRepository->getById($scopeData[1]);
- $attributeValues = $this->addressMapper->toFlatArray($customerAddress);
- }
- }
- $metadataForm = $this->_formFactory->create(
- $entityType,
- $formCode,
- $attributeValues,
- false,
- Form::DONT_IGNORE_INVISIBLE
- );
- return $metadataForm;
- }
- /**
- * Retrieve current customer ID
- *
- * @return int
- */
- private function getCurrentCustomerId()
- {
- $originalRequestData = $this->getRequest()->getPostValue(CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER);
- $customerId = isset($originalRequestData['entity_id'])
- ? $originalRequestData['entity_id']
- : null;
- return $customerId;
- }
- /**
- * 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);
- }
- }
- }
|