Magento 2.1.5 Как создать модуль, который может использовать функции подслушивания (AddAttribute в моем случае)
Я хочу создать модуль, который создает продукты magento из xml-файла. Итак, у меня есть модуль с командой php bin/magento LCB:import path/to/xml
. Он загружает xml-файл с пользовательскими атрибутами, которые необходимо создать. Я знаю, как создать атрибут с помощью InstallData.php или обновленные данные.
Мне нужно
$eavSetup->addAttribute()
Функция в моей модели. Возможно ли вообще расширить модель таким образом?
Я не нашел ничего полезного в своем случае. Ниже приведен мой код. У меня есть ошибки в:
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
Проблема в том, что это:
$eavsetup требует $настройки
$для настройки требуется $ресурс
$ресурсу требуется что-то с интерфейсом и так далее... все еще не работает
Код:
namespace LCB\Import\Model;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Module\Setup;
use Magento\Framework\App\ResourceConnection;
use Magento\Setup\Module\Setup\ResourceConfig;
use Magento\Setup\Module\ConnectionFactory;
use magento\framework\App\DeploymentConfig;
use magento\framework\App\DeploymentConfig\Reader;
use Magento\Framework\App\Filesystem\DirectoryList;
use magento\framework\Config\File\ConfigFilePool;
use magento\framework\Filesystem\DriverPool;
class Importer
{
private $eavSetupFactory;
private $objectManager;
public function __construct()
{
$this->objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$this->eavSetupFactory = new EavSetupFactory($this->objectManager);
}
public function createAttribute($attributes)
{
$dirList = new DirectoryList(BP);
$driverPool = new DriverPool();
$configFilePool = new ConfigFilePool();
$Reader = new Reader($dirList, $driverPool, $configFilePool);
$DeploymentConfig = new DeploymentConfig($Reader);
$ConnectionFactory = new ConnectionFactory();
$ResourceConfig = new ResourceConfig();
$resource = new ResourceConnection($ResourceConfig, $ConnectionFactory, $DeploymentConfig);
$setup = new Setup($resource);
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
foreach ($attributes as $attribute){
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
$attribute,
[
'type' => 'text',
'backend' => '',
'frontend' => '',
'label' => $attribute,
'input' => '',
'class' => '',
'source' => '',
'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
'visible' => true,
'required' => false,
'user_defined' => false,
'default' => '',
'searchable' => false,
'filterable' => false,
'comparable' => false,
'visible_on_front' => false,
'used_in_product_listing' => true,
'unique' => false,
'apply_to' => ''
]
);
}
}
}
Главный вопрос:
Как реализовать функцию AddAttribute() из eav в моей модели или это невозможно?
Редактировать:
@B G Кавинга Я пытался сделать это еще раньше. Давайте попробуем этот способ. Я набираю команду LCB: импорт, затем выполняю функцию() из моего класса команд называемый. В этой функции создается новый импортер, затем мне нужно вызвать createAttribute();
Если не в функции createAttribute(), мне нужно создать EAVSETUP в моем классе команд при создании нового импотента. Поэтому мне нужно создать $eavsetupfactory, $setup и $setup требуется интерфейс moduledatasetup и так далее...
Мне нужно правильно создать весь $eavsetupfactory. Что требует большого количества зависимостей. Поэтому мне нужно создать около 20 или даже больше "новых" объектов (я думаю, это не очень хорошо практика). Итак, как правильно реализовать этот $eavsetupfactory?
Вот упомянутая функция выполнения:
class ImportCommand extends Command
{
protected function execute(InputInterface $input, OutputInterface $output)
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$eavSetupFactory = new EavSetupFactory($objectManager);
$context = new Context(); //Context requires a lot of dependencies and dependencies requires other too
$setup = new DataSetup($context); //requires ModuleDataSetupInterface
$Importer = new Importer($eavSetupFactory, $setup);
//load attributes
$Importer->createAttribute($attributes);
}
}
2 answers
Не используйте ключевое слово new для создания объекта, вместо этого введите требуемый объект с помощью конструктора. Читать http://devdocs.magento.com/guides/v2.0/extension-dev-guide/depend-inj.html Попробуйте выполнить следующий код:
<?php
namespace BGKavinga\Examples\Model;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
class Importer
{
/**
* @var ModuleDataSetupInterface
*/
private $setup;
/**
* Init
*
* @param EavSetupFactory $eavSetupFactory
* @param ModuleDataSetupInterface $setup
*/
public function __construct(EavSetupFactory $eavSetupFactory, ModuleDataSetupInterface $setup)
{
$this->eavSetupFactory = $eavSetupFactory;
$this->setup = $setup;
}
/**
* @param $attributes
*/
public function createAttribute($attributes)
{
/** @var EavSetup $eavSetup */
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->setup]);
foreach ($attributes as $attribute) {
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
$attribute,
[
'type' => 'text',
'backend' => '',
'frontend' => '',
'label' => $attribute,
'input' => '',
'class' => '',
'source' => '',
'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
'visible' => true,
'required' => false,
'user_defined' => false,
'default' => '',
'searchable' => false,
'filterable' => false,
'comparable' => false,
'visible_on_front' => false,
'used_in_product_listing' => true,
'unique' => false,
'apply_to' => ''
]
);
}
}
}
Проверьте модуль здесь. https://github.com/bgkavinga/sample-code/raw/master/magento2-create-product-attributes.tar.gz
@B G Кавинга спасибо, ваш ответ привел меня на правильный путь. Я не знаю, хорошее ли это решение, но оно работает для меня. Я только что добавил в свой конструктор ImportCommand вот так.
use LCB\Import\Model\Importer;
class ImportCommand extends Command
{
private $importer;
public function __construct(Importer $importer)
{
parent::__construct();
$this->importer = $importer;
}
}