Add a custom xml file to define configurations - Magento 2
Published: 2021-03-18 08:42:43

Paboda/LoginDemo/etc/panel_config.xml
```
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:noNamespaceSchemaLocation="panel_config_list.xsd">
    <panel_config_list>
        <group>
            <url_label>Extension settings</url_label>
            <url_link>admin/system_config</url_link>
            <area>backend</area>
            <position>1</position>
        </group>
        <group>
            <url_label>Familiar experience</url_label>
            <url_link>customer/otp/login/</url_link>
            <area>frontend</area>
            <position>1</position>
        </group>
        <group>
            <url_label>Configure and Buy</url_label>
            <url_link>link/to/product</url_link>
            <area>button</area>
            <position>1</position>
        </group>
        <group>
            <url_label>Back to product</url_label>
            <url_link>link/to/product</url_link>
            <area>link</area>
            <position>1</position>
        </group>
    </panel_config_list>
</config>
```

Paboda/LoginDemo/etc/panel_config_list.xsd
```
<?xml version="1.0" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="config">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="1" maxOccurs="unbounded" name="panel_config_list" type="panelConfigList" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="panelConfigList">
        <xs:sequence>
            <xs:element minOccurs="1" maxOccurs="unbounded" name="group" type="panelConfigs" />
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="panelConfigs">
        <xs:sequence>
            <xs:element name="url_label" />
            <xs:element name="url_link" />
            <xs:element name="area" />
            <xs:element name="position" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="panelConfigButton">
        <xs:sequence>
            <xs:element minOccurs="1" maxOccurs="unbounded" name="buy" type="panelButtonConfig" />
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="panelButtonConfig">
        <xs:sequence>
            <xs:element name="url_label" />
            <xs:element name="url_link" />
        </xs:sequence>
    </xs:complexType>
</xs:schema>
```

Paboda/LoginDemo/etc/di.xml
```
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="PanelConfigReader" type="Magento\Framework\Config\Reader\Filesystem">
        <arguments>
            <argument name="converter" xsi:type="object">Paboda\LoginDemo\Model\Config\Converter</argument>
            <argument name="schemaLocator" xsi:type="object">Paboda\LoginDemo\Model\Config\SchemaLocator</argument>
            <argument name="fileName" xsi:type="string">panel_config.xml</argument>
        </arguments>
    </virtualType>
    <type name="Paboda\LoginDemo\Model\Config\Data">
        <arguments>
            <argument name="reader" xsi:type="object">PanelConfigReader</argument>
            <argument name="cacheId" xsi:type="string">panel_config_list_cache</argument>
        </arguments>
    </type>
    <preference for="Paboda\LoginDemo\Model\Config\DataInterface" type="Paboda\LoginDemo\Model\Config\Data" />
</config>

```

Paboda/LoginDemo/Model/Config/Converter.php
```
<?php
namespace Paboda\LoginDemo\Model\Config;

use Magento\Framework\Config\ConverterInterface;

class Converter implements ConverterInterface
{
    /**
     * @inheritDoc
     */
    public function convert($source)
    {
        $config = $source->getElementsByTagName('group');

        $configInfo = [];
        foreach ($config as $group) {
            $info = [];

            foreach ($group->childNodes as $groupInfo) {
                if ($groupInfo->nodeType != XML_ELEMENT_NODE) {
                    continue;
                }

                $info[$groupInfo->nodeName] = (string)$groupInfo->nodeValue;
            }

            $configInfo[] = $info;
        }
        $keys = array_column($configInfo, 'position');
        array_multisort($keys, SORT_ASC, $configInfo);
        return $configInfo;
    }
}
```

Paboda/LoginDemo/Model/Config/SchemaLocator.php
```
<?php
namespace Paboda\LoginDemo\Model\Config;

use Magento\Framework\Config\SchemaLocatorInterface;
use Magento\Framework\Module\Dir;

class SchemaLocator implements SchemaLocatorInterface
{
    /**
     * @var string|null
     */
    protected $_schema = null;

    /**
     * @var string|null
     */
    protected $_perFileSchema = null;

    /**
     * SchemaLocator constructor.
     *
     * @param Dir\Reader $moduleReader
     */
    public function __construct(\Magento\Framework\Module\Dir\Reader $moduleReader)
    {
        $etcDir = $moduleReader->getModuleDir(Dir::MODULE_ETC_DIR, 'Paboda_LoginDemo');
        $this->_schema = $etcDir . '/panel_config_list.xsd';
        $this->_perFileSchema = $etcDir . '/panel_config_list.xsd';
    }

    /**
     * Get schema
     *
     * @return string|null
     */
    public function getSchema()
    {
        return $this->_schema;
    }

    /**
     * Get path to schema
     *
     * @return string|null
     */
    public function getPerFileSchema()
    {
        return $this->_perFileSchema;
    }
}
```

Paboda/LoginDemo/Model/Config/Data.php
```
<?php
namespace Paboda\LoginDemo\Model\Config;

class Data extends \Magento\Framework\Config\Data
{
}
```

Paboda/LoginDemo/Model/Config/DataInterface.php
```
<?php
namespace Paboda\LoginDemo\Model\Config;

interface DataInterface
{
}
```

On a model define the method and call the method in a phtml if needed:
```
<?php
namespace Paboda\LoginDemo\Model;

use Magento\Backend\Model\Url as BackendUrl;
use Magento\Framework\UrlInterface;
use Magento\Store\Model\StoreManagerInterface;
use Paboda\LoginDemo\Model\Config\Data as PanelConfig;

class Panel
{
    /**
     * @var PanelConfig
     */
    protected $config;

    /**
     * Panel constructor.
     *
     * @param PanelConfig $config
     */
    public function __construct(
        PanelConfig $config
    ) {
        $this->config = $config;
    }

    /**
     * Get configurations from xml
     *
     * @param string $area
     * @return array|mixed|null
     */
    public function getPanelConfigData($area)
    {
        $xmlConfig = $this->config->get();
        $filterBy = $area;

        $arr = array_filter($xmlConfig, function ($var) use ($filterBy) {
            return ($var['area'] == $filterBy);
        });

        return $arr;
    }
}
```