MageStackDay bonus question for 500pts Bounty AND a the possibility of winning a free Z-Ray license for a year. More info can be found >> here <<
The questions are provided/inspired by Magento 2 core developer Anton Kril.
Question:
I'm creating an extension that has a separate set of configurations.
This means I cannot use config.xml
or routes.xml
or fieldset.xml
or any other config xml files magento has.
Example.
Let's say I'm defining a 'table' config that has rows an columns. I could use this xml below. (call it table.xml
)
<table xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="path/to/table.xsd">
<row id="row1">
<column id="col1" sort="10" attr1="val1">
<label>Col 1</label>
</column>
</row>
<row id="row2">
<column id="col1" sort="10" attr1="val1">
<label>Col 1</label>
</column>
<column id="col2" sort="20" disabled="true" attr1="val2" >
<label>Col 2</label>
</column>
<column id="col3" sort="15" attr1="val1">
<label>Col 3</label>
</column>
</row>
</table>
But if an other extension contains table.xml
I want it to be picked up by the config reader and the 2 or more xml files should be merged. I mean if the second file looks like this
<table xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="path/to/table.xsd">
<row id="row1">
<column id="col2" sort="10" attr1="val2">
<label>Col 2</label>
</column>
</row>
<row id="row2">
<column id="col1" sort="10" attr1="val5" />
</row>
</table>
the result will be that the second column is added to the first row and the value for attr1
is overwritten by the second xml:
<table ....>
<row id="row1">
<column id="col1" sort="10" attr1="val1"> <!-- from first xml -->
<label>Col 1</label>
</column>
<column id="col2" sort="10" attr1="val2"><!-- from second xml-->
<label>Col 2</label>
</column>
</row>
<row id="row2">
<column id="col1" sort="10" attr1="val5"><!--they apear in both xmls with the same path and id and second one overrides the value for `attr1`-->
<label>Col 1</label>
</column>
<column id="col2" sort="20" disabled="true" attr1="val2"><!-- from first xml -->
<label>Col 2</label>
</column>
<column id="col3" sort="15" attr1="val1"><!-- from first xml -->
<label>Col 3</label>
</column>
</row>
</table>
In Magento 1 I could have done this just by calling
$merged = Mage::getConfig()->loadModulesConfiguration('table.xml')
->applyExtends();
How can I do the same for Magento 2?
Best Answer
In Magento 2 this is handled by the
\Magento\Framework\Config\Reader\Filesystem
class. This class allows you specify the xml file you want to merge.The following part will merge all files found in the available modules and merge the output (snippet from
\Magento\Framework\Config\Reader\Filesystem
)In the solution I created the class above is extended to supply the xml file needed and specify where the xsd file to validate can be found (see https://github.com/Genmato/MageStackTable for complete example):
To get the merged data you can then call:
The output is then an array representation of the merged xml.
EDIT:
To test the way the files are read I created a working example (see https://github.com/Genmato/MageStackTable). Updated the answer with the solution build.