Skip to content

Config field backend model (system.xml) not used for default value (config.xml) #7741

@kweij

Description

@kweij

Preconditions

Magento 2.1.2

Steps to reproduce

Create a config field with a custom backend model, such as:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <tab id="oops" sortOrder="110">
            <label>Oops</label>
        </tab>
        <section id="oops_theme" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Theme</label>
            <tab>oops</tab>
            <resource>Oops_Theme::config</resource>
            <group id="homepage" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Homepage</label>
                <field id="menu" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Primary Actions</label>
                    <frontend_model>Oops\Theme\Block\Adminhtml\Form\Field\Menu</frontend_model>
                    <backend_model>Oops\Theme\Model\System\Config\Backend\Json</backend_model>
                </field>
            </group>
        </section>
    </system>
</config>

Here I use backend model Oops\Theme\Model\System\Config\Backend\Json. This model is looks like this:

namespace Oops\Theme\Model\System\Config\Backend;

use Magento\Framework\App\Config\Value;

class Json extends Value
{
    /**
     * Process data after load
     *
     * @return void
     */
    protected function _afterLoad()
    {
        $value = $this->getValue();
        $value = json_decode($value, true);
        $this->setValue($value);
    }

    /**
     * Prepare data before save
     *
     * @return void
     */
    public function beforeSave()
    {
        $value = $this->getValue();
        unset($value['__empty']);
        $value = json_encode($value, JSON_PRETTY_PRINT);
        $this->setValue($value);
    }
}

Expected result

Performs json_decode() after loading data from the configuration and json_encode() before saving the data to the database. Expected is that the _afterLoad() method gets evoked, unregardless of wether the configuration is retrieved from database or config.xml, however ...

Actual result

The _afterLoad() method gets evoked only after loading the configuration value from the database, and not after loading the configuration from config.xml. This causes default configuration from config.xml to be passed to the form-element as string in stead of Array, resulting in empty configuration fields in the admin interface.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area: FrontendComponent: ConfigFixed in 2.3.xThe issue has been fixed in 2.3 release lineIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedIssue: Format is validGate 1 Passed. Automatic verification of issue format passedIssue: Ready for WorkGate 4. Acknowledged. Issue is added to backlog and ready for developmentbug report

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions