88 private $settingChecker;
103 \
Magento\Framework\Event\ManagerInterface $eventManager,
105 \
Magento\Framework\DB\TransactionFactory $transactionFactory,
112 parent::__construct(
$data);
113 $this->_eventManager = $eventManager;
114 $this->_configStructure = $configStructure;
115 $this->_transactionFactory = $transactionFactory;
117 $this->_configLoader = $configLoader;
118 $this->_configValueFactory = $configValueFactory;
131 public function save()
135 $sectionId = $this->getSection();
136 $groups = $this->getGroups();
137 if (empty($groups)) {
144 $deleteTransaction = $this->_transactionFactory->create();
146 $saveTransaction = $this->_transactionFactory->create();
150 $extraOldGroups = [];
152 foreach ($groups as
$groupId => $groupData) {
153 $this->_processGroup(
164 $groupChangedPaths = $this->getChangedPaths($sectionId,
$groupId, $groupData, $oldConfig, $extraOldGroups);
165 $changedPaths = \array_merge($changedPaths, $groupChangedPaths);
169 $deleteTransaction->delete();
170 $saveTransaction->save();
173 $this->_appConfig->reinit();
176 $this->_eventManager->dispatch(
177 "admin_system_config_changed_section_{$this->getSection()}",
179 'website' => $this->getWebsite(),
180 'store' => $this->getStore(),
181 'changed_paths' => $changedPaths,
184 }
catch (\Exception $e) {
186 $this->_appConfig->reinit();
200 private function getOriginalFieldId(Group
$group,
string $fieldId): string
202 if (
$group->shouldCloneFields()) {
203 $cloneModel =
$group->getCloneModel();
206 foreach (
$group->getChildren() as $field) {
207 foreach ($cloneModel->getPrefixes() as
$prefix) {
227 private function getField(
string $sectionId,
string $groupId,
string $fieldId): Field
230 $group = $this->_configStructure->getElement($sectionId .
'/' .
$groupId);
232 $field = $this->_configStructure->getElement($fieldPath);
246 private function getFieldPath(Field $field,
string $fieldId, array &$oldConfig, array &$extraOldGroups): string
253 $configPath = $field->getConfigPath();
254 if ($configPath && strrpos($configPath,
'/') > 0) {
256 $configGroupPath = substr($configPath, 0, strrpos($configPath,
'/'));
257 if (!isset($extraOldGroups[$configGroupPath])) {
258 $oldConfig = $this->
extendConfig($configGroupPath,
true, $oldConfig);
259 $extraOldGroups[$configGroupPath] =
true;
275 private function isValueChanged(array $oldConfig,
string $path, array $fieldData): bool
277 if (isset($oldConfig[
$path][
'value'])) {
278 $result = !isset($fieldData[
'value']) || $oldConfig[
$path][
'value'] !== $fieldData[
'value'];
280 $result = empty($fieldData[
'inherit']);
296 private function getChangedPaths(
301 array &$extraOldGroups
305 if (isset($groupData[
'fields'])) {
306 foreach ($groupData[
'fields'] as
$fieldId => $fieldData) {
308 $path = $this->getFieldPath($field,
$fieldId, $oldConfig, $extraOldGroups);
309 if ($this->isValueChanged($oldConfig,
$path, $fieldData)) {
310 $changedPaths[] =
$path;
315 if (isset($groupData[
'groups'])) {
316 $subSectionId = $sectionId .
'/' .
$groupId;
317 foreach ($groupData[
'groups'] as $subGroupId => $subGroupData) {
318 $subGroupChangedPaths = $this->getChangedPaths(
325 $changedPaths = \array_merge($changedPaths, $subGroupChangedPaths);
329 return $changedPaths;
347 protected function _processGroup(
352 array &$extraOldGroups,
354 \
Magento\Framework\DB\Transaction $saveTransaction,
355 \
Magento\Framework\DB\Transaction $deleteTransaction
357 $groupPath = $sectionPath .
'/' .
$groupId;
359 if (isset($groupData[
'fields'])) {
361 $group = $this->_configStructure->getElement($groupPath);
366 foreach ($groupData[
'fields'] as
$fieldId => $fieldData) {
367 $fieldsetData[
$fieldId] = $fieldData[
'value'] ??
null;
370 foreach ($groupData[
'fields'] as
$fieldId => $fieldData) {
371 $isReadOnly = $this->settingChecker->isReadOnly(
374 $this->getScopeCode()
383 $backendModel = $field->hasBackendModel()
384 ? $field->getBackendModel()
385 : $this->_configValueFactory->create();
387 if (!isset($fieldData[
'value'])) {
388 $fieldData[
'value'] =
null;
393 'group_id' =>
$group->getId(),
394 'scope' => $this->getScope(),
395 'scope_id' => $this->getScopeId(),
396 'scope_code' => $this->getScopeCode(),
397 'field_config' => $field->getData(),
398 'fieldset_data' => $fieldsetData,
400 $backendModel->addData(
$data);
403 $path = $this->getFieldPath($field,
$fieldId, $extraOldGroups, $oldConfig);
404 $backendModel->setPath(
$path)->setValue($fieldData[
'value']);
406 $inherit = !empty($fieldData[
'inherit']);
407 if (isset($oldConfig[
$path])) {
408 $backendModel->setConfigId($oldConfig[
$path][
'config_id']);
414 $saveTransaction->addObject($backendModel);
416 $deleteTransaction->addObject($backendModel);
419 $backendModel->unsConfigId();
420 $saveTransaction->addObject($backendModel);
425 if (isset($groupData[
'groups'])) {
426 foreach ($groupData[
'groups'] as $subGroupId => $subGroupData) {
427 $this->_processGroup(
448 if ($this->_configData ===
null) {
450 $this->_configData = $this->
_getConfig(
false);
465 $extended = $this->_configLoader->getConfigByPath(
$path, $this->getScope(), $this->getScopeId(), $full);
466 if (is_array($oldConfig) && !empty($oldConfig)) {
467 return $oldConfig + $extended;
484 throw new \UnexpectedValueException(
'Path must not be empty');
486 $pathParts = explode(
'/',
$path);
487 $keyDepth = count($pathParts);
488 if ($keyDepth !== 3) {
489 throw new \UnexpectedValueException(
490 "Allowed depth of configuration is 3 (<section>/<group>/<field>). Your configuration depth is " 491 . $keyDepth .
" for path '$path'" 495 'section' => $pathParts[0],
499 $pathParts[2] => [
'value' =>
$value],
513 private function initScope()
515 if ($this->getSection() ===
null) {
516 $this->setSection(
'');
518 if ($this->getWebsite() ===
null) {
519 $this->setWebsite(
'');
521 if ($this->getStore() ===
null) {
525 if ($this->getStore()) {
527 $store = $this->_storeManager->getStore($this->getStore());
528 $scopeId = (int)
$store->getId();
529 $scopeCode =
$store->getCode();
530 }
elseif ($this->getWebsite()) {
532 $website = $this->_storeManager->getWebsite($this->getWebsite());
540 $this->setScope($scope);
541 $this->setScopeId($scopeId);
542 $this->setScopeCode($scopeCode);
553 return $this->_configLoader->getConfigByPath(
572 $isSingleStoreMode = $this->_storeManager->isSingleStoreMode();
573 if (!$isSingleStoreMode) {
576 if (!$fieldConfig->showInDefault()) {
577 $websites = $this->_storeManager->getWebsites();
578 $singleStoreWebsite = array_shift(
$websites);
579 $dataObject->setScope(
'websites');
580 $dataObject->setWebsiteCode($singleStoreWebsite->getCode());
581 $dataObject->setScopeCode($singleStoreWebsite->getCode());
582 $dataObject->setScopeId($singleStoreWebsite->getId());
604 $data = $this->_appConfig->getValue(
$path, $this->getScope(), $this->getScopeCode());
elseif(isset( $params[ 'redirect_parent']))
_checkSingleStoreMode(\Magento\Config\Model\Config\Structure\Element\Field $fieldConfig, $dataObject)
getConfigDataValue($path, &$inherit=null, $configData=null)
__construct(\Magento\Framework\App\Config\ReinitableConfigInterface $config, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Config\Model\Config\Structure $configStructure, \Magento\Framework\DB\TransactionFactory $transactionFactory, \Magento\Config\Model\Config\Loader $configLoader, \Magento\Framework\App\Config\ValueFactory $configValueFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, SettingChecker $settingChecker=null, array $data=[])
setDataByPath($path, $value)
extendConfig($path, $full=true, $oldConfig=[])