29

Does Magento 2 have a high level abstraction that allows end-user-programmers to update configuration values in the core_config_data table? Or is using straight SQL the only way to do this in Magento 2?

i.e. in Magento 1, you could do something like this

$config_model = new Mage_Core_Model_Config();
$config_model->saveConfig('my/config/path', $unique_id, 'default', 0);

and save configuration values into core_config_data. Is there an equivalent in Magento 2?

6 Answers 6

25

There is the same saveConfig method: https://github.com/magento/magento2/blob/2.0.0/app/code/Magento/Config/Model/ResourceModel/Config.php#L26-L61

A usage example from the core: https://github.com/magento/magento2/blob/2.0.0/app/code/Magento/Payment/Observer/UpdateOrderStatusForPaymentMethodsObserver.php#L59-L64

3
  • +1 Useful, thank you! I'm going to leave the question open for a while to see if an @api marked answers bubble up to the top. Commented Dec 8, 2015 at 0:25
  • 1
    It does change the value in the database but it doesn't reflect on the config page UI
    –  coinhndp
    Commented Jul 28, 2020 at 12:56
  • @coinhndp clear your config cache Commented Jan 14, 2022 at 17:23
27

I wouldn't use a model or a resource model, but \Magento\Framework\App\Config\Storage\WriterInterface or \Magento\Framework\App\Config\ConfigResource\ConfigInterface (the first delegating to the second).

Pretty straight-forward, too:

use Magento\Framework\App\Config\Storage\WriterInterface;

class SomeClass {

    public function __construct(WriterInterface $configWriter)
    {
        $configWriter->save('some/config/path', 'some value');
    }
}
1
  • Thanks! I think this is the better approach/high level abstraction we should be using. Because \Magento\Framework\App\Config\Storage\WriterInterface is implemented by \Magento\Framework\App\Config\Storage\Writer which in turn uses \Magento\Config\Model\ResourceModel\Config.
    – Andrei
    Commented Sep 26, 2017 at 16:29
5

You can also use \Magento\Config\Model\Config::save. Below a simple sample:

$configData = [
    'section' => 'MY_SECTION',
    'website' => null,
    'store'   => null,
    'groups'  => [
        'MY_GROUP' => [
            'fields' => [
                'MY_FIELD' => [
                    'value' => $myValue,
                ],
            ],
        ],
    ],
];

// $this->configFactory --> \Magento\Config\Model\Config\Factory
/** @var \Magento\Config\Model\Config $configModel */
$configModel = $this->configFactory->create(['data' => $configData]);
$configModel->save();

This syntax is not "simple", but it's more safe for some case. Du to the save logic, the action might be slower than direct access to the db.

In my case, $value need to be encrypted. In system.xml, I set the backend model for the field, and the save logic encrypt the data.

Edit: \Magento\Config\Model\Config::setDataByPath more simple to use

5

For a high level abstraction I'd inject Magento\Framework\App\Config\Storage\WriterInterface into the constructor of a data setup script:

use Magento\Framework\App\Config\Storage\WriterInterface; 

public function __construct(WriterInterface $configWriter) {...}

Then use the save() method, for example:

$website = $this->websiteRepository->get('main_website'); // inject Magento\Store\Model\WebsiteRepository;

$this->configWriter->save('general/country/default', 'US', ScopeInterface::SCOPE_WEBSITES, $website->getId()); // inject Magento\Store\Model\ScopeInterface;

Notes: Use the plural form of scopes: websites / stores in Magento\Store\Model\ScopeInterface

0

Here a complete sample to handle Magento 2 configuration programatically.

In my case, i add to clear cache too, else changes does not appear in Store > Config.

/**
 * @var \Magento\Config\Model\ResourceModel\Config
 */
protected $resourceConfig;

/**
 * @var \Magento\Framework\App\Cache\TypeListInterface
 */
protected $cacheTypeList;

public function __construct(
    \Magento\Config\Model\ResourceModel\Config $resourceConfig,
    \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
) {
    $this->resourceConfig = $resourceConfig;
    $this->cacheTypeList = $cacheTypeList;
}

public function process()
{
    $this->resourceConfig->saveConfig(
        'my/config/path',
        $unique_id,
        \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT,
        0
    );
     $this->cacheTypeList->cleanType(\Magento\Framework\App\Cache\Type\Config::TYPE_IDENTIFIER);
}
1
  • I clear the cache like your code but it still doesn't show
    –  coinhndp
    Commented Jul 28, 2020 at 13:02
0

PHP 7.4 (Support ended Jan 2023)

private $configWriter;

private $reinitableConfig;

public function __construct(
    \Magento\Framework\App\Config\Storage\WriterInterface $configWriter,
    \Magento\Framework\App\Config\ReinitableConfigInterface $reinitableConfig,
) {
    $this->configWriter = $configWriter;
    $this->reinitableConfig = $reinitableConfig;
}

public function apply(): void
{
    $this->configWriter->save(PageHelper::XML_PATH_HOME_PAGE, 'homepage');
    $this->reinitableConfig->reinit();

    // your actions with not-yet initialized updated config goes here
}

PHP 8.1

public function __construct(
    private readonly \Magento\Framework\App\Config\Storage\WriterInterface $configWriter,
    private readonly \Magento\Framework\App\Config\ReinitableConfigInterface $reinitableConfig,
) {}

public function apply(): void
{
    $this->configWriter->save(PageHelper::XML_PATH_HOME_PAGE, 'homepage');
    $this->reinitableConfig->reinit();

    // your actions with not-yet initialized updated config goes here
}
1
  • Note : This syntax is supported from PHP8.1 and above (so Magento 2.4.4 and abode). For older version you will need to adapt this a bit.
    – Cladiuss
    Commented Jun 26, 2023 at 12:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.