| Current Path : /home/rtorresani/www/vendor/magento/module-config/Controller/Adminhtml/System/Config/ |
| Current File : //home/rtorresani/www/vendor/magento/module-config/Controller/Adminhtml/System/Config/Save.php |
<?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 <core@magentocommerce.com>
* @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;
}
}