声明式方案以及Magento 2中的问题

大家好 该出版物一开始并没有假装为真理的标题,而只是我个人的观点,如果您分享得很好,如果不是,请在评论中进行讨论。

因此,更接近重点。 在Magento 2.3及更高版本中,有一个“邦尼”作为声明方案。 这个声明式方案是什么? 如果我们转到Magento文档,那么它是用黑白写的-“声明性方案旨在简化Magento的安装和更新”。

一切似乎都很棒,因为在开发人员不得不编写大量安装和升级脚本之前(在M1中,它们通常有些噩梦),直到2.3版之前,必须根据任务保留一定数量的脚本,即:

InstallSchema-安装模块以配置数据库结构时启动的此类。
InstallData-安装模块以初始化数据库表数据时启动的此类。
UpgradeSchema-此类在模块更新以配置数据库结构时启动。
UpgradeData-在更新模块以从表中添加/删除数据时启动此类。
卸载 -启动此类以从数据库中删除数据和表。

同意,这比为每次打喷嚏编写单独的脚本要好。 但是事实证明这并不是很方便,因为我必须遵循版本控制,跟踪和了解这些脚本中的内容,此外,它们还成长为包含4000多个行的巨大“基础”。 结果,这种方法被证明是相当失败的。 文件的数量减少了,但是代码行的数量却增加了。

然后,声明式方案得以营救。 实际上,它归结为单个文件db_schema.xml 。 在其中存储数据库的最终状态。 也就是说,如果您需要模块的自定义表格,请在此文件中描述必要的字段,仅此而已。 接下来,洋红色将为您创建一个表格。 如果您需要更新先前已经创建的表,只需对db_schema.xml文件进行更改即可。(魔术将自己发生)。 无需监视版本控制,无需为模块的每个新版本编写数据库更新脚本,实际上无需进行不必要的操作。 同意-很酷。

但是,没有一勺焦油,药膏中就没有苍蝇。 (这不是错字,与magento一起工作的人会理解我的:))。

只有在使用自定义表时,声明式方案才是好的。 如果您需要以编程方式向产品或类别添加属性,进行INSERT或UPDATE或最终更改Schema中的某些内容,请编写补丁。 我们将在下面讨论它们。

例如,考虑为产品添加自定义属性。

1.让我们从在模块中创建以下类开始:
设置\补丁\数据\ AddAlternativeNameAttribute.php

首先,它将包含以下内容

<?php namespace Foo\Bar\Setup\Patch\Data; use Magento\Eav\Setup\EavSetupFactory; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; class AddAlternativeNameAttribute implements DataPatchInterface { /** @var ModuleDataSetupInterface */ private $moduleDataSetup; /** @var EavSetupFactory */ private $eavSetupFactory; /** * @param ModuleDataSetupInterface $moduleDataSetup * @param EavSetupFactory $eavSetupFactory */ public function __construct( ModuleDataSetupInterface $moduleDataSetup, EavSetupFactory $eavSetupFactory ) { $this->moduleDataSetup = $moduleDataSetup; $this->eavSetupFactory = $eavSetupFactory; } } 

DataPatchInterface期望实现三个功能: applygetDependenciesgetAliases

2. apply函数是创建属性元素的地方。 现在,无需在此处调用startSetup和endSetup函数,因为我们仅创建属性。 为此,创建一个EavSetupFactory实例,传递我们的moduleDataSetup对象,并添加我们的属性:

  /** * {@inheritdoc} */ public function apply() { /** @var EavSetup $eavSetup */ $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]); $eavSetup->addAttribute('catalog_product', 'alternative_name', [ 'type' => 'varchar', 'label' => 'Alternative Name', 'input' => 'text', 'used_in_product_listing' => true, 'user_defined' => true, ]); } 

3. getDependencies函数需要一个字符串数组,其中包含依赖性类的名称。 这是专门针对声明性模式脚本而出现的新功能,它告诉Magento,它需要在安装脚本之前执行我们在此定义的“补丁”。 这就是Magento控制补丁脚本执行顺序的方式。

  /** * {@inheritdoc} */ public static function getDependencies() { return []; } 

4.最后一个getAliases函数,它定义此修补程序的别名。 由于我们不再指定版本号,因此类的名称可能会更改,如果发生这种情况,我们必须在此处指定旧的类名称,以使其不再第二次运行(补丁仅运行一次)

  /** * {@inheritdoc} */ public function getAliases() { return []; } 

最终课程将如下所示:

 <?php namespace Foo\Bar\Setup\Patch\Data; use Magento\Eav\Setup\EavSetup; use Magento\Eav\Setup\EavSetupFactory; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; class AddAlternativeNameAttribute implements DataPatchInterface { /** @var ModuleDataSetupInterface */ private $moduleDataSetup; /** @var EavSetupFactory */ private $eavSetupFactory; /** * @param ModuleDataSetupInterface $moduleDataSetup * @param EavSetupFactory $eavSetupFactory */ public function __construct( ModuleDataSetupInterface $moduleDataSetup, EavSetupFactory $eavSetupFactory ) { $this->moduleDataSetup = $moduleDataSetup; $this->eavSetupFactory = $eavSetupFactory; } /** * {@inheritdoc} */ public function apply() { /** @var EavSetup $eavSetup */ $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]); $eavSetup->addAttribute('catalog_product', 'alternative_name', [ 'type' => 'varchar', 'label' => 'Alternative Name', 'input' => 'text', 'used_in_product_listing' => true, 'user_defined' => true, ]); } /** * {@inheritdoc} */ public static function getDependencies() { return []; } /** * {@inheritdoc} */ public function getAliases() { return []; } } 

5.现在运行bin / magento setup:升级,以便应用我们的补丁。 对于已成功执行的所有补丁,Magento将一个条目插入patch_list数据库 ,其patch_name字段值等于我们类的值(Foo \ Bar \ Setup \ Patch \ Data \ AddAlternativeNameAttribute)。

6.从bin_list表中删除该值将在bin / magento安装程序:升级安装开始时重新运行补丁程序。 调试补丁程序时,此功能很有用。

结果:

+声明式方案简化了自定义表的工作
+无需监视版本控制
+轻松升级表中的数据并自定义表字段

-无法通过声明性方案向产品类别添加属性
-如果该模块对于版本2.1、2.2、2.3通用,则必须编写声明性方案和安装脚本。
-需要编写用于处理核心表的补丁程序。

也许在可预见的将来,当M2完全转换为声明性方案并且不需要编写补丁时,它将非常方便。 但是,这是否会发生以及何时发生,问题仍然悬而未决。

Source: https://habr.com/ru/post/zh-CN462795/


All Articles