Magento 2: Programmatically Add a Value to `core_config_data`
-
13-12-2019 - |
Question
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?
Solution
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
OTHER TIPS
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');
}
}
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
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
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);
}