1

I'm trying to ad a customer attribute outside a Setup Script.

To be more specific inside a console command using CustomerSetupFactory::updateAttribute method.

I get an error caused by DI.

Argument 1 passed to Magento\Setup\Module\DataSetup::__construct() must be an instance of Magento\Framework\Module\Setup\Context, instance of Magento\Framework\ObjectManager\ObjectManager given, called in /var/www/magento/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 93 in /var/www/magento/setup/src/Magento/Setup/Module/DataSetup.php on line 57

Is there any reason why not to do what I'm trying to achieve?

Is there any way to fix my problem?

What I did

Cleared cache. Cleared var/generation and var/di manually. Ran setup:di:compile

Thanks

EDIT:

This works if:

1. Clear var/generation manually 2. Do not run setup:di:compile and run my CLI Command 

It does not work if setup:di:copile ran. I have to mention that setup:di:compile ran without error

What is causing this behavior is setup:di:compile at fault?

1
  • Can you paste the code here please, looks like it is parent constructor issue, where you don't add the parent constructor parameters in your class I guess. Thanks. Commented Feb 9, 2018 at 12:51

1 Answer 1

3

I did following way and working fine with compile. You can try.

app/code/SR/Stackexchange/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"> <type name="Magento\Framework\Console\CommandList"> <arguments> <argument name="commands" xsi:type="array"> <item name="add_customer_attribute_command" xsi:type="object">SR\Stackexchange\Console\Command\AddCustomerAttribute</item> </argument> </arguments> </type> </config> 

app/code/SR/Stackexchange/Console/Command/AddCustomerAttribute.php

 namespace SR\Stackexchange\Console\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Output\OutputInterface; use Magento\Customer\Model\Customer; use Magento\Customer\Setup\CustomerSetup; use \Magento\Framework\Setup\ModuleDataSetupInterface; class AddCustomerAttribute extends Command { /** * Customer setup factory * * @var \Magento\Customer\Setup\CustomerSetupFactory */ private $customerSetupFactory; /** * @var ModuleDataSetupInterface */ private $setup; /** * @var \Magento\Framework\App\State */ private $appState; /** * @var \Symfony\Component\Console\Output\OutputInterface */ private $output; /** * AddCustomerAttribute constructor. * * @param \Magento\Customer\Setup\CustomerSetupFactory $customerSetupFactory * @param ModuleDataSetupInterface $setup * @param \Magento\Framework\App\State $appState */ public function __construct( \Magento\Customer\Setup\CustomerSetupFactory $customerSetupFactory, ModuleDataSetupInterface $setup, \Magento\Framework\App\State $appState ) { $this->customerSetupFactory = $customerSetupFactory; $this->setup = $setup; $this->appState = $appState; $this->appState->setAreaCode(\Magento\Framework\App\Area::AREA_ADMINHTML); parent::__construct(); } /** * Initialization of the command * * @return void */ protected function configure() { $this->setName('sr:customerattribute') ->setDescription('Add customer attribute'); parent::configure(); } /** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { ini_set('memory_limit', '-1'); $this->output = $output; try { $output->writeln( "Start" ); /** @var CustomerSetup $customerSetup */ $customerSetup = $this->customerSetupFactory->create(['setup' => $this->setup]); // Add new customer attribute $customerSetup->addAttribute( Customer::ENTITY, 'company', [ 'label' => 'Company', 'input' => 'text', 'required' => false, 'sort_order' => 1000, 'position' => 1000, 'visible' => true, 'system' => false, 'is_used_in_grid' => true, 'is_visible_in_grid' => false, 'is_filterable_in_grid' => false, 'is_searchable_in_grid' => false, 'default' => '0' ] ); // add attribute to form /** @var $attribute */ $attribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'company'); $attribute->setData('used_in_forms', ['adminhtml_customer', 'customer_account_create', 'customer_account_edit']); $attribute->save(); $output->writeln( "<info>Completed</info>" ); } catch (\Exception $e) { $output->writeln('<error>' . $e->getMessage() . '</error>'); if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { $output->writeln($e->getTraceAsString()); } return; } } } 

Command

 php bin/magento sr:customerattribute 
1
  • Thank you for your answer. As a suggestion I would recommend not setting the area code in the constructor(or at least try catch it) as it might result in an Area code is already set error, if there are two cli commands that are setting the code in the constructor. As you might know Magento instantiates all cli commands at a certain point. thanks again. Commented Feb 9, 2018 at 16:46

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.