Так вот, ближе к делу. В версии Magento 2.3 и выше появилась такая «плюшка» как декларативная схема. Что же это такое декларативная схема? Если мы обратимся к документации мадженто, то там черным по белому написано — «Декларативая схема направлена на упрощение процессов установки и обновления Magento».
Вроде бы все здорово, ведь раньше разработчикам приходилось писать очень много install и upgrade скриптов (в М1 вообще был маленький кошмар с ними), вплоть до версии 2.3 нужно было в зависимости от задач держать энное количество скриптов, а именно:
InstallSchema — этот класс запускается при установке модуля для настройки структуры базы данных
InstallData — этот класс запускается при установке модуля для инициализации данных таблицы базы данных.
UpgradeSchema — этот класс запускается при обновлении модуля для настройки структуры базы данных
UpgradeData — этот класс запускается при обновлении модуля для добавления / удаления данных из таблицы.
Uninstall — этот класс запускается для удаления данных и таблиц из базы.
Согласитесь, это уже лучше чем для каждого чиха писать отдельный скрипт. Но и это оказалось не очень удобно, так как приходилось следить за версионностью, отслеживать и понимать что у тебя содержится в этих скриптах, и к тому же они разростались в огромные «портянки» на 4000+ строк. В итоге и этот подход оказался довольно провальным. Количесто файлов сократилось, но количество строк кода увеличилось.
Тут то и пришла на помощь декларативная схема. По факту все свелось к одному файлу — db_schema.xml. В котором вы храните конечное состояние базы данных. То есть если вам для модуля нужна кастомная таблица, вы описываете нужные поля в данном файле и все. Дальше маджента сама для вас создаст таблицу. В случае если вам нужно обновить уже созданную ранее таблицу, вы просто вносите правки в файл db_schema.xml и все (магия произойдет сама). Не нужно следить за версионностью, не нужно для каждой новой версии модуля писать скрипты обновления базы, по факту не нужно делать лишних операция. Согласитесь — это круто.
Но ведь не бывает бочки дегтя без ложки дегтя. (Это не опечатка, кто работает с мадженто меня поймет 🙂 ).
Декларативная схема хороша только при работе с кастомными таблицами. Если вам нужно добавить программно атрибут в продукт или категорию, сделать INSERT или UPDATE, или в конце концов изменить что-то в Schema — будьте любезны написать патчи. О них ниже и поговорим.
Для примера рассмотрим добавление кастомного атрибута для продукта.
1. Начнем с того, что в модуле создадим следующий класс:
Setup\Patch\Data\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 ожидает реализации трех функций: apply, getDependencies и getAliases.
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:upgrade для того, чтобы наш патч применился. Для всех патчей, которые успешно выполнены, Magento вставляет запись в таблицу базы данных patch_list со значением поля patch_name, равным значению нашего класса (Foo\Bar\Setup\Patch\Data\AddAlternativeNameAttribute).
6. Удаление значения из таблицы patch_list приведет к повторному выполнению патча при запуске установки bin/magento setup:upgrade. Данная функциональность будет полезна при отладке патчей.
Итог:
+ Декларативная схема упрощает работу с кастомными таблицами
+ Отсутствие надобности следить за версионностью
+ Легкий апгред данных в таблицах и кастомизация полей таблиц
— Отсутствие возможности добавлять атрибуты в продукт-категорию через декларативную схему
— Если модуль универсальный для версий 2.1, 2.2, 2.3 придется писать и декларативную схему и инсталл скрипты.
— Необходимость написания патчей для работы с core’вскими таблицами.
Возможно, в обозримом будущем, когда M2 полностью перейдет на декларативную схему и отпадет надобность писать патчи, это будет супер удобно. Но будет ли это и когда случится, вопрос остается открытым.
ссылка на оригинал статьи https://habr.com/ru/post/462795/
Добавить комментарий