如何在Magento 2中使用系统配置和帮助程序

Magento 2开发人员的本教程将研究系统配置和帮助程序的使用,这些操作程序旨在简化您在Magento商店中的工作。助手包含实用功能,可以在任何地方调用。

在本指南中,我们将重点介绍Magento 1中配置和帮助程序之间的差异和变化,并将使用代码创建配置部分,如下面的屏幕快照所示,其中显示了一个新标签(’INVIQA’),一个部分(’ Inviqa”)和一个表单组(“ General”)。 

目录结构

下面的屏幕截图显示了文件结构的布局,它与Magento 1非常相似。但是,由于Magento 2现在有了特定于区域的配置概念,所以system.xml位于adminhtml目录中更深层的一个级别。所以路径是etc/adminhtml/system.xml。

System config file

因此,如前所述,系统配置文件位于  etc/adminhtml/system.xml。在示例代码中,它看起来像这样:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <tab id="inviqa" translate="label" sortOrder="1000">
            <label>Inviqa</label>
        </tab>
        <section id="inviqa" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Inviqa</label>
            <tab>inviqa</tab>
            <resource>Inviqa_SystemConfigExample::inviqa</resource>
            <group id="general" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>General</label>
                <field id="enabled" type="select" translate="label,comment,tooltip" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Enabled</label>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                    <config_path>inviqa/general/enabled</config_path>
                    <comment>Helpful message about using this field.</comment>
                    <tooltip>Longer helpful message about using this field.</tooltip>
                </field>
                <field id="title" type="text" translate="label" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Title</label>
                    <validate>required-entry alphanumeric</validate>
                    <config_path>inviqa/general/title</config_path>
                    <depends>
                        <field id="enabled">1</field>
                    </depends>
                </field>
                <field id="secret" type="obscure" translate="label" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Secret</label>
                    <validate>required-entry</validate>
                    <backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
                    <config_path>inviqa/general/secret</config_path>
                    <depends>
                        <field id="enabled">1</field>
                    </depends>
                </field>
                <field id="option" type="select" translate="label" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Option</label>
                    <source_model>Inviqa\SystemConfigExample\Model\Config\Source\Option</source_model>
                    <config_path>inviqa/general/option</config_path>
                    <depends>
                        <field id="enabled">1</field>
                    </depends>
                </field>
            </group>
        </section>
    </system>
</config>

现在,让我们尝试将其分解以更好地理解它:

<tab id="inviqa" translate="label" sortOrder="1000">
            <label>Inviqa</label>
</tab>

这个xml代码很容易解释;它向左边的选项卡菜单添加了一个新的可扩展选项卡。

<section id="inviqa" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Inviqa</label>
            <tab>inviqa</tab>
            <resource>Inviqa_SystemConfigExample::inviqa</resource>
            ...
        </section>

这段代码向选项卡添加了一个新部分。这里有一些事情需要进一步分解。

首先,section属性showInDefault=”1″ showInWebsite=”1″ showInStore=”1″表示该section的范围可见性。在这种情况下,该部分将显示在所有范围(默认、网站和商店)。配置范围在Magento 2和他们在Magento 1相同的工作。

其次,inviqa通过引用前面定义的tab id属性的值将该部分分配给新选项卡。

最后,Inviqa_SystemConfigExample::inviqa指定了将在etc/acl.xml中引用的资源id。下面将进一步说明这一点:

 <group id="general" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>General</label>
                ...
            </group>

此代码将新的字段分组添加到该部分。范围属性的工作方式与上述相同。

 <field id="enabled" type="select" translate="label,comment,tooltip" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Enabled</label>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                    <config_path>inviqa/general/enabled</config_path>
                    <comment>Helpful message about using this field.</comment>
                    <tooltip>Longer helpful message about using this field.</tooltip>
                </field>

此代码将一个新的选择字段(select)添加到组中。它在source_model属性中指定核心模型Magento\Config\ model \Config\Source\Yesno来提供要选择的值。在Magento 1中,这种在选择列表中显示Yes/No选项的格式是在系统配置中显示布尔选项的首选方式。

它还在config_path属性中指定了“inviqa/general/enabled”。这个属性完全是可选的,默认情况下,Magento将仅使用配置的xml结构来确定配置路径。

但是,定义自己的配置路径可能很有用,原因有几个。首先,您可能需要重构您的系统配置,这可能会导致默认路径的更改(否则需要重新配置)。

其次,如果您有许多层次的组嵌套,您可能想要简化或平化配置路径。在本例中,值“inviqa/general/enabled”实际上与从xml结构中派生的值相同,因此可以删除它而不产生任何影响。

下面是和标签,它们用于显示额外的信息。前一个标记的内容显示在字段的下面,当鼠标悬停在工具提示图标上时显示后一个标记的内容,工具提示图标在字段的右边以问号的形式显示。

为了使这些文本字符串可用于翻译特性,标签被添加到包含字段标签的translate属性中,以逗号分隔的列表形式,即translate=”label,comment,tooltip”。


               <field id="title" type="text" translate="label" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Title</label>
                    <validate>required-entry alphanumeric</validate>
                    <config_path>inviqa/general/title</config_path>
                    <depends>
                        <field id="enabled">1</field>
                    </depends>
                </field>

此代码将一个纯文本(text)字段添加到组中。它通过向validate标记指定一个以空格分隔的字符串来添加验证。在这里,它确保必须输入一个值,并且该值必须仅为字母数字。所有验证选项都可以在以下文件中找到:vendor/magento/magento2-base/lib/web/mage/ valid. js。

该代码还添加了一个  depends 标签,其中包含field 引用“已启用”字段的  标签。这样的效果是,仅在“启用”选择字段设置为“是”时才显示“标题”字段。示例代码中的其余字段也具有相同的依赖性。此策略可用于整理配置,并使其更明显哪些字段需要首先填写。

<field id="secret" type="obscure" translate="label" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Secret</label>
                    <validate>required-entry</validate>
                    <backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
                    <config_path>inviqa/general/secret</config_path>
                    <depends>
                        <field id="enabled">1</field>
                    </depends>
                </field>

此代码将密码(password)字段添加到该组。这是通过将字段类型属性设置为“obscure” 来完成的。但是,该字段本身仍将存储为纯文本。

因此,除此之外,它还使用<backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model> 加密core_config_data 表中存储的值  。

<field id="option" type="select" translate="label" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Option</label>
                    <source_model>Inviqa\SystemConfigExample\Model\Config\Source\Option</source_model>
                    <config_path>inviqa/general/option</config_path>
                    <depends>
                        <field id="enabled">1</field>
                    </depends>
                </field>

最后,这段代码通过引用自定义源模型添加了一个带有自定义选项集的选择字段。示例源文件的内容如下所示:

<?php

namespace Inviqa\SystemConfigExample\Model\Config\Source;

use Magento\Framework\Option\ArrayInterface;

class Option implements ArrayInterface
{
    public function toOptionArray()
    {
        return [
            ['value' => '1', 'label' => __('Option A')],
            ['value' => '2', 'label' => __('Option B')],
            ['value' => '3', 'label' => __('Option C')],
        ];
    }
}

如您所见,该文件只是实现了ArrayInterface,并有一个toOptionArray,它返回一组选项值。

ACL config file

与Magento 1中一样,使用ACL(访问控制列表)定义文件来控制对Magento 2中配置部分的访问。

设置ACL访问是一种良好实践,因为它允许管理员创建具有执行某些日常职责所需的访问权限的自定义角色。这反过来又提高了应用程序的稳定性和安全性,因为如果角色拥有最小的特权,它就能最大限度地减少密钥设置被错误更改的可能性——或者,在用户未经授权访问的情况下,它能最大限度地减少可能造成的损害。用户角色可以在System >用户角色中设置。

ACL资源定义位于etc/ ACL .xml的模块中。

在我们的示例代码中,它看起来是这样的:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
    <acl>
        <resources>
            <resource id="Magento_Backend::admin">
                <resource id="Magento_Backend::stores">
                    <resource id="Magento_Backend::stores_settings">
                        <resource id="Magento_Config::config">
                            <resource id="Inviqa_SystemConfigExample::inviqa" title="Inviqa" />
                        </resource>
                    </resource>
                </resource>
            </resource>
        </resources>
    </acl>
</config>

这个文件的大部分是样板代码,但关键行是,它将上面在etc/system.xml (‘Inviqa_SystemConfigExample::inviqa’)中定义的资源id绑定到Magento配置ACL。这将使它在System >用户角色> {User} >角色资源中可见,如下面的屏幕截图所示。

Default config file

有时,您希望为自定义表单字段提供默认配置值。这可以通过创建etc/config.xml非常简单地实现,如下所示。

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <inviqa>
            <general>
                <title>Inviqa</title>
            </general>
        </inviqa>
    </default>
</config>

在此,我们确保将在标题字段中显示默认值’Inviqa’。xml结构与从中定义的配置路径匹配  etc/adminhtml/system.xml,即“ inviqa / general / title”。

如果您已使用中的  config_path 属性  etc/adminhtml/system.xml 来创建非默认配置路径,则此处的xml结构将需要与其匹配。

Helper file

设置好系统配置并将其保存到core_config_data表之后,就可以在整个Magento系统中使用它了。

建议(尽管不是强制性的)使用助手来检索值。这种方法有很多好处。首先,配置路径仅在一个位置进行硬编码,因此不会在整个代码库中重复。这使代码维护更加容易。其次,抽象帮助程序已经  Magento\Framework\App\Config\ScopeConfigInterface 注入以便立即使用。

在我们的示例代码中的助手看起来是这样的:

<?php

namespace Inviqa\SystemConfigExample\Helper;

use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Encryption\EncryptorInterface;

class Data extends AbstractHelper
{
    /**
     * @var EncryptorInterface
     */
    protected $encryptor;

    /**
     * @param Context $context
     * @param EncryptorInterface $encryptor
     */
    public function __construct(
        Context $context,
        EncryptorInterface $encryptor
    )
    {
        parent::__construct($context);
        $this->encryptor = $encryptor;
    }

    /*
     * @return bool
     */
    public function isEnabled($scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT)
    {
        return $this->scopeConfig->isSetFlag(
            'inviqa/general/enabled',
            $scope
        );
    }

    /*
     * @return string
     */
    public function getTitle($scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT)
    {
        return $this->scopeConfig->getValue(
            'inviqa/general/title',
            $scope
        );
    }

    /*
     * @return string
     */
    public function getSecret($scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT)
    {
        $secret = $this->scopeConfig->getValue(
            'inviqa/general/secret',
            $scope
        );
        $secret = $this->encryptor->decrypt($secret);
        
        return $secret;
    }

    /*
     * @return string
     */
    public function getOption($scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT)
    {
        return $this->scopeConfig->getValue(
            'inviqa/general/option',
            $scope
        );
    }
}