![]() 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-config/Controller/Adminhtml/System/Config/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Config\Controller\Adminhtml\System\Config; use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Config\Controller\Adminhtml\System\AbstractConfig; use Magento\Framework\Exception\LocalizedException; /** * System Configuration Save Controller * * @author Magento Core Team <[email protected]> * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Save extends AbstractConfig implements HttpPostActionInterface { /** * Backend Config Model Factory * * @var \Magento\Config\Model\Config\Factory */ protected $_configFactory; /** * @var \Magento\Framework\Cache\FrontendInterface */ protected $_cache; /** * @var \Magento\Framework\Stdlib\StringUtils */ protected $string; /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Config\Model\Config\Structure $configStructure * @param \Magento\Config\Controller\Adminhtml\System\ConfigSectionChecker $sectionChecker * @param \Magento\Config\Model\Config\Factory $configFactory * @param \Magento\Framework\Cache\FrontendInterface $cache * @param \Magento\Framework\Stdlib\StringUtils $string */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Config\Model\Config\Structure $configStructure, \Magento\Config\Controller\Adminhtml\System\ConfigSectionChecker $sectionChecker, \Magento\Config\Model\Config\Factory $configFactory, \Magento\Framework\Cache\FrontendInterface $cache, \Magento\Framework\Stdlib\StringUtils $string ) { parent::__construct($context, $configStructure, $sectionChecker); $this->_configFactory = $configFactory; $this->_cache = $cache; $this->string = $string; } /** * @inheritdoc */ protected function _isAllowed() { return parent::_isAllowed() && $this->isSectionAllowed(); } /** * Checks if user has access to section. * * @return bool */ private function isSectionAllowed(): bool { $sectionId = $this->_request->getParam('section'); $isAllowed = $this->_configStructure->getElement($sectionId)->isAllowed(); if (!$isAllowed) { $groups = $this->getRequest()->getPost('groups'); $fieldPath = $this->getFirstFieldPath($groups, $sectionId); $fieldPaths = $this->_configStructure->getFieldPaths(); $fieldPath = $fieldPaths[$fieldPath][0] ?? $sectionId; $explodedConfigPath = explode('/', $fieldPath); $configSectionId = $explodedConfigPath[0] ?? $sectionId; $isAllowed = $this->_configStructure->getElement($configSectionId)->isAllowed(); } return $isAllowed; } /** * Return field path as string. * * @param array $elements * @param string $fieldPath * @return string */ private function getFirstFieldPath(array $elements, string $fieldPath): string { $groupData = []; foreach ($elements as $elementName => $element) { if (!empty($element)) { $fieldPath .= '/' . $elementName; if (!empty($element['fields'])) { $groupData = $element['fields']; } elseif (!empty($element['groups'])) { $groupData = $element['groups']; } if (!empty($groupData)) { $fieldPath = $this->getFirstFieldPath($groupData, $fieldPath); } break; } } return $fieldPath; } /** * Get groups for save * * @return array|null */ protected function _getGroupsForSave() { $groups = $this->getRequest()->getPost('groups'); $files = $this->getRequest()->getFiles('groups'); if ($files && is_array($files)) { /** * Carefully merge $_FILES and $_POST information * None of '+=' or 'array_merge_recursive' can do this correct */ foreach ($files as $groupName => $group) { $data = $this->_processNestedGroups($group); if (!empty($data)) { if (!empty($groups[$groupName])) { $groups[$groupName] = array_merge_recursive((array)$groups[$groupName], $data); } else { $groups[$groupName] = $data; } } } } return $groups; } /** * Process nested groups * * @param mixed $group * @return array */ protected function _processNestedGroups($group) { $data = []; if (isset($group['fields']) && is_array($group['fields'])) { foreach ($group['fields'] as $fieldName => $field) { if (!empty($field['value'])) { $data['fields'][$fieldName] = ['value' => $field['value']]; } } } if (isset($group['groups']) && is_array($group['groups'])) { foreach ($group['groups'] as $groupName => $groupData) { $nestedGroup = $this->_processNestedGroups($groupData); if (!empty($nestedGroup)) { $data['groups'][$groupName] = $nestedGroup; } } } return $data; } /** * Custom save logic for section * * @return void */ protected function _saveSection() { $method = '_save' . $this->string->upperCaseWords($this->getRequest()->getParam('section'), '_', ''); if (method_exists($this, $method)) { $this->{$method}(); } } /** * Advanced save procedure * * @return void */ protected function _saveAdvanced() { $this->_cache->clean(); } /** * Save configuration * * @return \Magento\Backend\Model\View\Result\Redirect */ public function execute() { try { // custom save logic $this->_saveSection(); $section = $this->getRequest()->getParam('section'); $website = $this->getRequest()->getParam('website'); $store = $this->getRequest()->getParam('store'); $configData = [ 'section' => $section, 'website' => $website, 'store' => $store, 'groups' => $this->_getGroupsForSave(), ]; $configData = $this->filterNodes($configData); $groups = $this->getRequest()->getParam('groups'); if (isset($groups['country']['fields'])) { if (isset($groups['country']['fields']['eu_countries'])) { $countries = $groups['country']['fields']['eu_countries']; if (empty($countries['value']) && !isset($countries['inherit'])) { throw new LocalizedException( __('Something went wrong while saving this configuration.') ); } } } /** @var \Magento\Config\Model\Config $configModel */ $configModel = $this->_configFactory->create(['data' => $configData]); $configModel->save(); $this->_eventManager->dispatch( 'admin_system_config_save', ['configData' => $configData, 'request' => $this->getRequest()] ); $this->messageManager->addSuccess(__('You saved the configuration.')); } catch (\Magento\Framework\Exception\LocalizedException $e) { $messages = explode("\n", $e->getMessage()); foreach ($messages as $message) { $this->messageManager->addError($message); } } catch (\Exception $e) { $this->messageManager->addException( $e, __('Something went wrong while saving this configuration:') . ' ' . $e->getMessage() ); } $this->_saveState($this->getRequest()->getPost('config_state')); /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); return $resultRedirect->setPath( 'adminhtml/system_config/edit', [ '_current' => ['section', 'website', 'store'], '_nosid' => true ] ); } /** * Filter paths that are not defined. * * @param string $prefix Path prefix * @param array $groups Groups data. * @param string[] $systemXmlConfig Defined paths. * @return array Filtered groups. * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ private function filterPaths(string $prefix, array $groups, array $systemXmlConfig): array { $flippedXmlConfig = array_flip($systemXmlConfig); $filtered = []; foreach ($groups as $groupName => $childPaths) { //When group accepts arbitrary fields and clones them we allow it $group = $this->_configStructure->getElement($prefix .'/' .$groupName); if (array_key_exists('clone_fields', $group->getData()) && $group->getData()['clone_fields']) { $filtered[$groupName] = $childPaths; continue; } $filtered[$groupName] = ['fields' => [], 'groups' => []]; //Processing fields if (array_key_exists('fields', $childPaths)) { foreach ($childPaths['fields'] as $field => $fieldData) { //Constructing config path for the $field $path = $prefix .'/' .$groupName .'/' .$field; $element = $this->_configStructure->getElement($path); if ($element && ($elementData = $element->getData()) && array_key_exists('config_path', $elementData) ) { $path = $elementData['config_path']; } //Checking whether it exists in system.xml if (array_key_exists($path, $flippedXmlConfig)) { $filtered[$groupName]['fields'][$field] = $fieldData; } } } //Recursively filtering this group's groups. if (array_key_exists('groups', $childPaths) && $childPaths['groups']) { $filteredGroups = $this->filterPaths( $prefix .'/' .$groupName, $childPaths['groups'], $systemXmlConfig ); if ($filteredGroups) { $filtered[$groupName]['groups'] = $filteredGroups; } } $filtered[$groupName] = array_filter($filtered[$groupName]); } return array_filter($filtered); } /** * Filters nodes by checking whether they exist in system.xml. * * @param array $configData * @return array */ private function filterNodes(array $configData): array { if (!empty($configData['groups'])) { $systemXmlPathsFromKeys = array_keys($this->_configStructure->getFieldPaths()); $systemXmlPathsFromValues = array_reduce( array_values($this->_configStructure->getFieldPaths()), 'array_merge', [] ); //Full list of paths defined in system.xml $systemXmlConfig = array_merge($systemXmlPathsFromKeys, $systemXmlPathsFromValues); $configData['groups'] = $this->filterPaths($configData['section'], $configData['groups'], $systemXmlConfig); } return $configData; } }