11

So far I know that when uninstalling a custom module, it is possible to remove custom tables or columns added by custom module by using uninstall.php which extends \Magento\Framework\Setup\UninstallInterface. But how to remove custom attributes added by InstallData.php when uninstalling the module? Thanks in advance!

CarComp
  • 1,246
  • 1
  • 15
  • 34
Ricky.C
  • 2,182
  • 9
  • 33
  • 54

3 Answers3

12

In a module, you would use the following code that utilizes dependency injection for uninstallation. It works equally well anywhere else, just be sure to inject the EavSetupFactory into the constructor and then utilize its methods to do the work.

<?php

namespace Company\Modulename\Setup {

    class Uninstall implements \Magento\Framework\Setup\UninstallInterface
    {

        protected $eavSetupFactory;

        public function __construct(\Magento\Eav\Setup\EavSetupFactory $eavSetupFactory)
        {
            $this->eavSetupFactory = $eavSetupFactory;
        }



        public function uninstall(\Magento\Framework\Setup\SchemaSetupInterface $setup, \Magento\Framework\Setup\ModuleContextInterface $context)
        {
            $setup->startSetup();

            $eavSetup = $this->eavSetupFactory->create();

            $entityTypeId = 1; // Find these in the eav_entity_type table
            $eavSetup->removeAttribute($entityTypeId, 'attribute_code');

            $setup->endSetup();

        }
    }

}

Additionally, using this method will cause the eav attribute to properly remove itself from all tables, since they are linked using constraints.

BTW, I recommend using PHPStorm + xdebug. You will learn SO much about how all these things connect together.

CarComp
  • 1,246
  • 1
  • 15
  • 34
  • What file and where does this go? – Mark Aug 25 '16 at 12:27
  • Its Uninstall.php. Its goes in the module setup folder. Check out the namespace. It always should match the pathname. – CarComp Aug 26 '16 at 18:31
  • 2
    You can also use Customer::ENTITY or Product::ENTITY etc. instead of 1 or 4. (use Magento\Catalog\Model\Product; use Magento\Customer\Model\Customer;) – Jānis Elmeris Nov 10 '17 at 08:27
  • In addition to @JānisElmeris suggestion, consider defining your attribute name as a const in your setup file, so you don't need to use magic strings which can break your application if you decide to change a name and forget to change it in your uninstall script – Tschallacka May 05 '21 at 09:18
3

use Magento\Customer\Model\Customer class instead of entity id like 1 and 2.

<?php
namespace Custom\Module\Setup;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Customer\Model\Customer;

class InstallData implements InstallDataInterface
{
private $eavSetupFactory;

public function __construct(EavSetupFactory $eavSetupFactory) 
{
 $this->eavSetupFactory = $eavSetupFactory;
}

 public function install(ModuleDataSetupInterface $setup, ModuleContextInterface 
  $context)
   {
    $setup->startSetup();

   $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
   $eavSetup->removeAttribute(Customer::ENTITY, 'attribute_code_here');

  $setup->endSetup();
  }
}

Happy Coding !!

Rohit Chauhan
  • 560
  • 5
  • 17
2

You can use \Magento\Eav\Api\AttributeRepositoryInterface::delete for this.

KAndy
  • 20,811
  • 3
  • 49
  • 59
  • True, but its implied he is building a custom module, so that means assuming the method for creation and deletion is programmatic. Using the api is somewhat the wrong approach, however, you could backtrack your way from the AttributeRepositoryInterface to the class and methods that actually do the work. – CarComp Jul 12 '16 at 20:02
  • 1
    @CarComp, Using the API is only one proper approach, if you interested in work of you module on new version of Magento. Magento use BC policy only for api. And private implementation can be changed at any time without notification – KAndy Jul 13 '16 at 07:01
  • I just re-read what I wrote. I am not saying its the wrong approach for everyone, I meant just in relation to his question. He was asking how to do it in php. – CarComp Jul 13 '16 at 12:12
  • 1
    API - it interfaces with @api annotation, not Web API. Sorry if I something miss understudy – KAndy Jul 13 '16 at 13:07